#include <iostream>         // cin és cout parancsok
#include <fstream>          // fájlkezelés
#include <vector>           // vector adattípushoz
#include <map>              // map (szótár) adattípushoz
#include <set>              // set (halmaz) adattípushoz
#include <iomanip>          // setprecision I/O manipulálás
#include <algorithm>        // sort függvény

#define N 12345             // teljes lakosság létszáma

using namespace std;

struct jelolt
{
    int vk;                 // választókörzet (1-8 közötti egész szám)
    int szavazat;           // a jelöltre leadott szavazatok száma
    string vnev;            // jelölt vezetékneve
    string knev;            // jelölt keresztneve
    string part;            // jelöltet támogató párt (GYEP,HEP,ZEP,TISZ,-)
};

int szumma;     // globális változó
set<string> partnevek;      // pártnevek halmaza, csak azért, hogy legyen halmazra is példa

void F1(vector<jelolt> &j)
{
    ifstream fbe;
    fbe.open("szavazatok.txt");
    jelolt temp;
    while(fbe>>temp.vk&&fbe>>temp.szavazat&&fbe>>temp.vnev&&fbe>>temp.knev&&fbe>>temp.part)
    {
        j.push_back(temp);              // a vector feltöltése
        partnevek.insert(temp.part);    // a halmaz feltöltése
    }
    fbe.close();
}

void F2(vector<jelolt> j)
{
    cout << "2. feladat" << endl;
    printf("A helyhatósági választáson %d képviselőjelölt indult.\n",j.size());
}

void F3(vector<jelolt> j)
{
    cout << "3. feladat" << endl;
    string vnev, knev;
    cout << "Vezetéknév: ";
    cin >> vnev;
    cout << "Keresztnév: ";
    cin >> knev;
    bool van=false;
    for(auto elem:j)                // klasszikus keresés helyett egy for ciklus - nem elegáns, de praktikus
    {
        if(elem.vnev==vnev&&elem.knev==knev)
        {
            cout << elem.szavazat << " szavazatot kapott." << endl;
            van=true;
            break;
        }
    }
    if(van==false)
    {
        cout << "Ilyen nevű képviselőjelölt nem szerepel a nyilvántartásban!" << endl;
    }
}

void F4(vector<jelolt> j)
{
    cout << "4. feladat" << endl;
    szumma=0;
    for(auto elem:j)
    {
        szumma+=elem.szavazat;
    }
    float arany=((float)szumma/(float)N)*100;
    printf("A választáson %d állampolgár, a jogosultak %.2f%%-a vett részt.\n",szumma,arany);
}

void F5(vector<jelolt> j)
{
    cout << "5. feladat" << endl;
    struct part
    {
        int sz;             // szavazatok száma, egy adott pártra
        string nev;         // párt neve
    };
    map<string,part> partok;        // szótár adattípus, csak hogy ilyen is legyen
                                    // szótárunk kulcs a párt neve, értékei egy struktúra lesz
    for(auto partnev:partnevek)
    {
        partok[partnev].sz=0;       // pártokra leadott szavazatok összesítéséhez inicializálás
    }
    partok["GYEP"].nev="Gyümölcsevők Pártja";       // a struktúra nev mezőjét "manuálisan" töltjük fel
    partok["ZEP"].nev="Zöldségevők Pártja";
    partok["TISZ"].nev="Tejivók Pártja";
    partok["HEP"].nev="Húsevők Pártja";
    partok["-"].nev="Független jelöltek";
    for(auto elem:j)
    {
        partok[elem.part].sz+=elem.szavazat;        // az összesítés ilyen egyszerű a szótár típusnak köszönhetően
    }
    float arany;
    // szótár esetén a "first" a kulcs, a "second" az értéket jelenti
    for(auto elem:partok)
    {
        arany=((float) elem.second.sz / (float) szumma)*100;
        cout << elem.second.nev << ": \t" << fixed << setprecision(2) << arany << "%" << endl;
    }
}

bool szavazat_szerint(jelolt a, jelolt b)
{
    return a.szavazat > b.szavazat; // szavazat szerint csökkenő sorrendbe rendezés
}

bool vk_szavazat_szerint(jelolt a, jelolt b)
{
    // választókerület szerint növekvő, azon belül szavazat szerint csökkenő sorrendbe rendezés
    return (a.vk < b.vk) || (a.vk==b.vk&&a.szavazat>b.szavazat);
}

void F6_F7(vector<jelolt> j)
{
    cout << "6. feladat" << endl;
    vector<jelolt> temp,temp2;
    temp=j;
    temp2=j;
    sort(temp.begin(),temp.end(),szavazat_szerint);
    sort(temp2.begin(),temp2.end(),vk_szavazat_szerint);
    int max_szavazat=temp[0].szavazat;
    for(auto elem:temp)
    {
        if( elem.szavazat==max_szavazat)
        {
            cout << elem.vnev << " " << elem.knev << " \t";
            if(elem.part=="-") cout << "független"; else cout << elem.part;
            cout << "\t (" << elem.szavazat << ")" << endl;
        }

    }
    cout << "7. feladat" << endl;
    ofstream fki;
    fki.open("kepviselok.txt");
    jelolt akt=temp2[0];
    cout << akt.vk << " " << " " << akt.vnev << " " << akt.knev << " ";
    if(akt.part=="-") cout << "független"; else cout << akt.part << endl;
    fki << akt.vk << " " << " " << akt.vnev << " " << akt.knev << " ";
    if(akt.part=="-") fki << "független"; else fki << akt.part << endl;
    for(auto elem:temp2)
    {
        if(elem.vk!=akt.vk)
        {
            akt=elem;
            cout << akt.vk << " " << " " << akt.vnev << " " << akt.knev << " ";
            if(akt.part=="-") cout << "független"; else cout << akt.part;
            cout << endl;
            fki << akt.vk << " " << " " << akt.vnev << " " << akt.knev << " ";
            if(akt.part=="-") fki << "független"; else fki << akt.part;
            fki << endl;
        }
    }
    fki.close();
}

int main()
{
    setlocale(LC_ALL,"");
    vector<jelolt> jeloltek;
    jeloltek.reserve(100);
    F1(jeloltek);
    F2(jeloltek);
    F3(jeloltek);
    F4(jeloltek);
    F5(jeloltek);
    F6_F7(jeloltek);

    return 0;
}

