//Készítette:Gregorics Tibor
//Dátum:     2010.02.26.
//Feladat:   Mindenkinek három négyese

#include <iostream>
#include <vector>

using namespace std;

// Ellenőrző függvények
bool Nat(int n) { return n>=0; }         // természetes szám
bool Mark(int n){ return n>=1 && n<=5; } // 1 és 5 közötti egész szám
bool All(int n) { return true; }         // tetszőleges egész szám

int ReadInt(const string &msg, const string &err, bool check(int) = All);
void ReadMarks(vector<vector<int> > &naplo);
bool ForAllThree4(const vector<vector<int> > &naplo);
int  Number4(const vector<int> &v);

//Feladat: 	    Vizsgálni, hogy vajon minden tanulónak pontosan három négyese van-e
//Bemenő adatok:vector<vector<int> > naplo - osztályzási napló jegyeinek mátrixa
//Kimenő adatok:bool l                     - válasz
//Tevékenység:	Feltölti a naplo-t, majd kiértékeli és kiírja az eredményt.
int main()
{
    vector<vector<int> > naplo;
// Beolvasás
    ReadMarks(naplo);
// Kiértékelés
    if (ForAllThree4(naplo)) {
        cout << "Mindenkinek pontosan három négyese van";
    } else {
        cout << "Van akinek nem három négyese van";
    }

    cout<<endl;
    return 0;
}

//Feladat: 	Megadott feltételt kielégítő egész számot olvas be.
//Bemenő adatok:string msg	    - kiírandó üzenet
//				string errormsg	- kiírandó hibaüzenet
//              bool check(int) - ellenőrző függvény
//Kimenő adatok:int n (visszatérési érték)  - beolvasott egész szám: visszatérési érték
//Tevékenység:	Billentyűzetről olvas be egy a check() feltételnek megfelelő
//		        egész számot.
int ReadInt(const string &msg, const string &err, bool check(int))
{
    int n;
    bool hiba;
    do{
        cout << msg;
        string str;
        cin >> str;
        n = atoi(str.c_str());
        hiba = n==0 && str!="0" || !check(n);
       if(hiba) cout << err << endl;
    }while(hiba);
    return n;
}

//Feladat: 	    Osztályzási napló feltöltése billentyűzetről
//Kimenő adatok:vector<vector<int> > naplo - osztályzási napló jegyeinek mátrixa
//Tevékenység:	Feltölti a naplo-t, majd kiértékeli és kiírja az eredményt.
void ReadMarks(vector<vector<int> > &naplo)
{
    int n = ReadInt("Tanulók száma: ", "Természetes szám!", Nat);
    int m = ReadInt("Tárgyak száma: ", "Természetes szám!", Nat);

    naplo.resize(n);
    for(int i=0; i<n; ++i)
    {
        naplo[i].resize(m);
        cout << i+1 << ". tanuló eredményei\n";
        for(int j=0; j<m; ++j)
        {
            cout << "\t" << j+1 << ". tantárgy: ";
            naplo[i][j] = ReadInt("","1 és 5 közötti szám!", Mark);
        }
    }
}

//Feladat: 	    Eldönti, hogy a mátrix minden sorában van-e pontosan három négyes
//Bemenő adatok:vector<vector<int> > naplo - osztályzási napló jegyeinek mátrixa
//Kimenő adatok:bool l                     - válasz
//Tevékenység:	Optimista lineáris keresés a mátrix sorai felett.
bool ForAllThree4(const vector<vector<int> > &naplo)
{
    bool l = true;
    int i = 0;
    while(l && i<(int)naplo.size()){
        l = Number4(naplo[i])==3;
        ++i;
    }
    return l;
}

//Feladat: 	   Megszámolja, hogy egy tömbben (mátrix adott sorában) hány négyes van
//Bemenő adatok:vector<int> v - osztályzási napló egy sora
//Kimenő adatok:int s         - válasz (visszatérési érték)
//Tevékenység:	Optimista lineáris keresés a mátrix sorai felett.
int Number4(const vector<int> &v)
{
    int s=0;
    for (int j=0; j<(int)v.size(); ++j){
        if (v[j]==4) ++s;
    }
    return s;
}

