Login
Order Now
Support
C++ Programming Task on Matrix

C++ Programming Task on Matrix

  • 19th Jan, 2022
  • 23:40 PM

#include <bits/stdc++.h>

using namespace std;

const int INF = 1000000000; // A very large number.

// Store the file names in a vector.
const vector<string> file_names = vector<string>({
    "Wolves.csv", 
    "Newcastle.csv", 
    "Man_City.csv", 
    "Leicester.csv", 
    "Norwich.csv", 
    "Crystal_Palace.csv", 
    "Watford.csv", 
    "Brighton.csv", 
    "Spurs.csv", 
    "Sheffield_Utd.csv", 
    "West_Ham.csv", 
    "Arsenal.csv", 
    "Everton.csv", 
    "Aston_Villa.csv", 
    "Man_Utd.csv", 
    "Bournemouth.csv", 
    "Burnley.csv", 
    "Chelsea.csv", 
    "Liverpool.csv", 
    "Southampton.csv",
});

// Store the valid 20 team names in a vector.
const vector<string> team_names = vector<string>({
    "Leicester", 
    "Wolves", 
    "Everton", 
    "Crystal Palace", 
    "Man City", 
    "Newcastle", 
    "Arsenal", 
    "Bournemouth", 
    "Brighton", 
    "Norwich", 
    "Liverpool", 
    "Watford", 
    "Southampton", 
    "Man Utd", 
    "Spurs", 
    "West Ham", 
    "Aston Villa", 
    "Sheffield Utd", 
    "Burnley", 
    "Chelsea",
});

// class Match. Stores the names and the corresponding scores of each match.
class Match{
    public:
        Match(string name1, string name2, int score1, int score2) 
          : name1(name1), name2(name2), score1(score1), score2(score2) {}
        string get_name1(){
            return name1;
        }
        string get_name2(){
            return name2;
        }
        int get_score1(){
            return score1;
        }
        int get_score2(){
            return score2;
        }
        
    private:
        string name1, name2; // `name1` represents Home Team, `name2` represents Away Team.
        int score1, score2; // `score1` represents score of Home Team, `score2` represents score of Away Team.
};

// class Team. Stores the total matches of a team.
class Team{
    public:
        Team(){}
        vector<Match> get_matches(){
            return matches;
        }
        void set_matches(Match& m){
            matches.push_back(m);
        }
        
    private:
        vector<Match> matches;
};

// Code to read a csv file and parse the inputs.
string strip(string& s){
    s = regex_replace(s, regex("^ +"), "");
    s = regex_replace(s, regex(" +$"), "");
    return s;
}

bool check(const string& s){
    for(const auto e : team_names){
        if(e == s) return true;
    }
    return false;
}

void read_csv(string file_name, Team& t){
    fstream fin;
    fin.open(file_name, ios::in);
    vector<string> row;
    string line, word, temp;
    bool flag = false;
    while(fin >> temp){
        row.clear();
        getline(fin, line);
        stringstream s(line);
        while(getline(s, word, '\t')){
            row.push_back(strip(word));
        }
        if(flag && row.size() == 6 && check(row[3]) && check(row[4])){  // Discarding inconsistent data. Some data is inconsistent because of misplaced tabs. 
            if(row[5].find('-') != -1){
                Match m(row[3], row[4], row[5][0]-'0', row[5][4]-'0');  // For played matches store the original score.
                t.set_matches(m);
            }
            else{ 
                Match m(row[3], row[4], -1, -1);  // For unplayed matches store -1 in the respective scores.
                t.set_matches(m);
            }
        }
        flag = true;
    }
}

// class EPL. Stores the total data of each and every team.
class EPL{
    public:
        EPL(){
            for(const auto file_name : file_names){
                Team t;
                string path = "Data/" + file_name;
                read_csv(path, t);
                teams.push_back(t);
            }
        }
        vector<Team> get_teams(){
            return teams;
        }
    
    private:
        vector<Team> teams;
};

// cout all team parameters. Just to check.
void print(EPL& epl){
    vector<Team> teams = epl.get_teams();
    cout << "Total number of teams : " << teams.size() << endl;
    for(auto& team : teams){
        vector<Match> matches = team.get_matches();
        cout << "-----------------------------------------------------------\n";
        cout << "Total matches for this team : " << matches.size() << endl;
        for(auto& match : matches){
            cout << match.get_name1() << " " << match.get_name2() << " " << match.get_score1() << " " << match.get_score2() << endl;
        }
        cout << "-----------------------------------------------------------\n";
    }
}

// The Matrix class. Stores the Home Team in the row index and the Away Team in the column index. 
// The corresponding index stores the score of Home Team - Away Team. 
// The matches which are not played are represented with INF.
class Matrix{
    public:
        Matrix(int size=20){
            N = size;
            NNZ = 0;
            matrix.assign(N, vector<double>(N, INF));
            I.assign(N, 0);
            J.assign(N, 0);
        }
        int get_size(){  // Returns the size of the matrix.
            return N;
        }
        void set_ij(int i, int j, int s1, int s2){
            assert(i < N && j < N);
            matrix[i][j] = s1-s2;
            if(s1 != s2) NNZ++;
            if(s1 > s2) I[i] += 1;
            else if (s1 < s2) J[j] += 1;
        }
        double get_ij(int i, int j){
            assert(i < N && j < N);
            return matrix[i][j];
        }
        void print_matrix(){
            for(int i=0; i<N; i++){
                for(int j=0;j<N; j++){
                    cout << matrix[i][j] << "\t";
                }
                cout << endl;
            }
        }
        int get_I(int i){
            return I[i];
        }
        int get_J(int j){
            return J[j];
        }
        
    private:
        vector<vector<double>> matrix;
        vector<int> I;  // i'th element stores the number of times team i won in Home play.
        vector<int> J;  // i'th element stores the number of times team i won in Away play.
        int N;
        int NNZ;
};

// Returns the index of the position of the team name in `team_names`.
int index(string team_name){
    for(int i=0; i<team_names.size(); i++){
        if(team_names[i] == team_name) return i;
    }
    return -1;  // This will not occur. Just for error checking.
}

template<typename T> void printElement(T t, const int& width){
    char separator = ' ';
    cout << left << setw(width) << setfill(separator) << t;
}


int main(){
    EPL epl;
    //print(epl);
    Matrix matrix;
    // Fill the matrix.
    vector<Team> teams = epl.get_teams();
    set<pair<int, int>> predict;
    //cout << "Total number of teams : " << teams.size() << endl;
    for(auto& team : teams){
        vector<Match> matches = team.get_matches();
        for(auto& match : matches){
            const int i = index(match.get_name1()), j = index(match.get_name2()), s1 = match.get_score1(), s2 = match.get_score2();
            if(s1 != -1 && s2 != -1)
                matrix.set_ij(i, j, s1, s2);
            else predict.insert({i, j});
        }
    }
    //matrix.print_matrix();
    vector<int> count(20, 0);
    // Now predicting.
    cout << "Prediction Table : \n";
    ofstream fout;
    fout.open("prediction.csv");
    cout << "HOME TEAM\t\t\tAWAY TEAM\t\t\tPREDICTION\n";
    fout << "HOME TEAM\tAWAY TEAM\tPREDICTION\n";
    cout << "-----------------------------------------------------------------------------------------------------" << endl;
    for(const auto& p : predict){
        int i = p.first, j = p.second;
        printElement(team_names[i], 32);
        printElement(team_names[j], 32);
        fout << team_names[i] << "\t" << team_names[j] << "\t";
        int team1_h = matrix.get_I(i)/2, team1_a = matrix.get_J(i)/2, team2_h = matrix.get_I(j)/2, team2_a = matrix.get_J(j)/2;
        if(team1_h > team2_a){
            cout << team_names[i] << " is predicted to win." << endl;
            fout << team_names[i] << " is predicted to win." << endl;
            count[i]++;
        }
        else if(team1_h < team2_a){
            cout << team_names[j] << " is predicted to win." << endl;
            fout << team_names[j] << " is predicted to win." << endl;
            count[j]++;
        }
        else{
            cout << "This match is predicted to be a draw." << endl;
            fout << "This match is predicted to be a draw." << endl;
        }
        cout << "-----------------------------------------------------------------------------------------------------" << endl;
    }
    fout.close();
    
    vector<pair<int, int>> standing;
    for(int i=0; i<20; i++){
        count[i] += (matrix.get_I(i) / 2) + (matrix.get_J(i) / 2);
        standing.push_back({-count[i], i});
    }
    
    sort(standing.begin(), standing.end());
    fout.open("standings.csv");
    cout << "STANDINGS - " << endl;
    printElement("TEAM NAME : ", 32);
    printElement("WINS : ", 32);
    printElement("LOST / DRAW : ", 32);
    cout << endl;
    fout << "TEAM NAME\tWINS\tLOST / DRAW\n";
    cout << "==============================================================================\n";
    for(const auto& p : standing){
        printElement(team_names[p.second], 32);
        printElement(to_string(-p.first), 32);
        printElement(to_string(38+p.first), 32);
        cout << endl;
        fout << team_names[p.second] << "\t" << -p.first << "\t" << 38+p.first << endl;
    }
    cout << "==============================================================================\n";
    fout.close();
    return 0;
}

// Run as : 
// $ g++ -std=c++17 -o main main.cpp
// $ ./main

// We can see in the output, in every instance where Liverpool is a Home Team it is expected to win.

Share this post

assignment helpassignment helperassignment expertsassignment writing services