#include <iostream>         // cin, cout
#include <fstream>          // fájkezelés
#include <vector>           // vector adattípushoz
#include <set>              // set (halmaz) adattípushoz
#include <ctime>            // random számghoz
#include <iomanip>          // setw parancs

using namespace std;

struct telek                // egy telket "leíró" struktúra
{
    int hazszam;
    int szelesseg;
    char kerites;
    int sorrend;            // fájlban elfoglalt eredeti sorrend (egyben a vásárlás sorrendje)
};

void F1(vector<telek> &prs,vector<telek> &ptl)
{
    ifstream fbe;
    fbe.open("kerites.txt");
    int oldal;                      // a fájl sorának első eleme, melyet arra használunk, hogy a házszámot megállapítsuk
    int prs_hsz=2,ptl_hsz=1;        // házszámok a páros és páratlan oldalon, ez kerül a struktúrába és a vectorba
    telek temp;                     // telek típusú átmeneti változó a fájlból beolvasott adatokhoz
    int i=1;                        // eredeti sorrendhez (lsd. 15.sor megjegyzése)
    while(fbe>>oldal&&fbe>>temp.szelesseg&&fbe>>temp.kerites)
    {
        if(oldal==0)    // páros oldalon vagyunk
        {
            temp.hazszam=prs_hsz;
            temp.sorrend=i;
            prs.push_back(temp);    // páros oldal vectorának feltöltése
            prs_hsz+=2;             // házszám "léptetése"
        }
        else
        {
            temp.hazszam=ptl_hsz;
            temp.sorrend=i;
            ptl.push_back(temp);    // páratlan oldal vectorának feltöltése
            ptl_hsz+=2;             // házszám "léptetése"
        }
        i++;    // sorrend növelése
    }
    fbe.close();
    // beolvasott adatok (páros és páratlan oldali vectorok) kiírása képernyőre
    for(auto elem:prs)
    {
        cout << elem.hazszam << " " << elem.szelesseg << " " << elem.kerites << " " << elem.sorrend << endl;
    }
    cout << "-------------------------------------------------------------------------" << endl;
    for(auto elem:ptl)
    {
        cout << elem.hazszam << " " << elem.szelesseg << " " << elem.kerites << " " << elem.sorrend << endl;
    }
}

void F2(vector<telek> prs,vector<telek> ptl)
{
    cout << "-------------------------------- 2. feladat --------------------------------" << endl;
    printf("Az eladott telkek száma: %d\n",prs.size()+ptl.size());
}

void F3(vector<telek> prs,vector<telek> ptl)
{
    cout << "-------------------------------- 3. feladat --------------------------------" << endl;
    string valasz;
    int hsz;
    // ha a párosoldali utolsó telek sorrend-száma azonos a teljes telekszámmal, akkor páros oldalon volt az utolsó telek
    if(prs[prs.size()-1].sorrend==(prs.size()+ptl.size()))      // itt van egy kis "hátránya" a kétvektoros megoldásunknak
    {
        valasz="páros";
        hsz=prs[prs.size()-1].hazszam;
    }
    else                                // egyébként a páratlan oldalon
    {
        valasz="páratlan";
        hsz=ptl[ptl.size()-1].hazszam;
    }
    cout << "A " << valasz << " oldalon adták el az utolsó telket." << endl;
    cout << "Az utolsó telek házszáma: " << hsz << endl;
}

void F4(vector<telek> ptl)
{
    cout << "-------------------------------- 4. feladat --------------------------------" << endl;
    // Keresünk egy házszámot a páratlan oldalról, amely melletti telken ugyanolyan színű a kerítés...
    // Feltételezheti, hogy van ilyen telek, a több ilyen közül elég az egyik ház számát megjeleníteni...
    int hsz;                        // ez nem házszám, hanem index a páratlanoldali vectorhoz
    set<char> temp={'#',':'};       // a "nem színek" halmaza
    for(auto i=0;i<ptl.size();i++)  // páratlan oldali vector bejárása
    {
        // ha nem eleme tempnek a kerites színe, és ugyanolyan, mint a következő
        if(temp.count(ptl[i].kerites)==0&&ptl[i].kerites==ptl[i+1].kerites)
        {
            hsz=i;      // akkor megjegyezzük az indexét
            break;      // és "kiugrunk" a ciklusból
        }
    }
    cout << "A szomszédossal egyezik a kerítés színe: " << ptl[hsz].hazszam << endl;
}

int kerites_hazszam(vector<telek> t,int hazszam)        // adott házszámú telek keresése a megfelelő vectorban
{
    int i=0;                                            // klasszikus lineáris keresés
    while(i<t.size()&&t[i].hazszam!=hazszam)
    {
        i++;
    }
    if(i<t.size()) return i;                            // ha van találat, visszaadja az indexét
    else return -1;                                     // egyébként -1-et
}

void F5(vector<telek> prs,vector<telek> ptl)
{
    cout << "-------------------------------- 5. feladat --------------------------------" << endl;

    char s;
    int hsz,k,bal,jobb;         // hsz - házszám, k - a megadott házszámú telek indexe és bal, jobb szomszéd indexe
    vector<telek> temp;         // ebbe kerül vagy a páros vagy páratlan oldali vector
    set<char> szomszedok;       // egy halmaz, amibe a szomszédok és az adott telek színe kerül

    cout << "Adjon meg egy házszámot! ";
    cin >> hsz;                 // házszám beolvasása

    srand(time(NULL));          // véletlenszám-generátor inicializálása
    if(hsz%2==0)                // ha házszám páros, akkor
    {
        k=kerites_hazszam(prs,hsz);     // házszám alapján megkeressük a telek indexét
        temp=prs;                       // temp-be kerül a párosoldali vector
    }
    else
    {
        k=kerites_hazszam(ptl,hsz);     // ugyanaz, mint a páros esetben...
        temp=ptl;
    }
    if(k!=-1)                           // ha találtunk ilyen telket, akkor
    {
        cout << "A kerítés színe / állapota: " << temp[k].kerites << endl;
        bal=k-1;jobb=k+1;                       // szomszédok indexe
        k==0 ? bal=k : bal=k-1;                 // legelső telket adtuk meg ---> ha igen, akkor a bal szomszéd maga a telek
        k==temp.size()-1 ? jobb=k : jobb=k+1;   // legutolsó telket adtuk meg, akkor a jobb szomszéd maga a telek
        for(int i=bal;i<=jobb;i++) {szomszedok.insert(temp[i].kerites);}    // szomszédok (és az adott telek) színének halmazba helyezése
        do      // véletlenszínek generálása...
        {
            s=char (65+rand()%26);
        }
        while(szomszedok.count(s)!=0);      //... amíg olyant nem generálunk, ami nincs a szomszed halmazban
        cout << "Egy lehetséges festési szín: " << s << endl;
    }
    else
    {
        cout << "Ilyen házszám nincs!" << endl;
    }
}

void F6(vector<telek> ptl)
{
    ofstream fki;
    fki.open("utcakep.txt");
    char szokoz=' ';
    string hazszam;
    for(auto t:ptl)
    {
        for(int i=0;i<t.szelesseg;i++) fki << t.kerites;        // telek szélességnek megfelelő számszor kerítés színének kiírása
    }
    fki << endl;
    for(auto t:ptl)
    {
        hazszam=to_string(t.hazszam);           // házszám stringé alakítása
        fki << hazszam << setw(t.szelesseg-hazszam.size()) << szokoz;   // házszám és megfelelő számú szóköz kiírása
    }
    fki << endl;
}

int main()
{
    setlocale(LC_ALL,"");
    vector<telek> parosoldal;
    vector<telek> paratlanoldal;
    F1(parosoldal,paratlanoldal);
    F2(parosoldal,paratlanoldal);
    F3(parosoldal,paratlanoldal);
    F4(paratlanoldal);
    F5(parosoldal,paratlanoldal);
    F6(paratlanoldal);
    return 0;
}
