aboutsummaryrefslogtreecommitdiff
path: root/challenge-009/paulo-custodio/cpp/ch-2.cpp
blob: fe621cfa336ce8a60acc53e24af02be162dbdc5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
Challenge 009

Challenge #2
Write a script to perform different types of ranking as described below:

1. Standard Ranking (1224): Items that compare equal receive the same ranking
   number, and then a gap is left in the ranking numbers.
2. Modified Ranking (1334): It is done by leaving the gaps in the ranking
   numbers before the sets of equal-ranking items.
3. Dense Ranking    (1223): Items that compare equally receive the same
   ranking number, and the next item(s) receive the immediately following
   ranking number.
*/

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

struct Score {
    int seq;
    int score;
    int rank;
};

bool rev_by_score(const Score& a, const Score& b) {
    return a.score > b.score;
}

bool by_seq(const Score& a, const Score& b) {
    return a.seq < b.seq;
}

void standard_ranking(vector<Score>& scores) {
    sort(scores.begin(), scores.end(), rev_by_score);
    int rank = 1;
    for (size_t i = 0; i < scores.size(); i++) {
        int count = 0;
        for (size_t j = i; j < scores.size() && scores[i].score == scores[j].score; j++) {
            count++;
            scores[j].rank = rank;
        }
        rank += count;
        i += count - 1;
    }
    sort(scores.begin(), scores.end(), by_seq);
}

void modified_ranking(vector<Score>& scores) {
    sort(scores.begin(), scores.end(), rev_by_score);
    int rank = 1;
    for (size_t i = 0; i < scores.size(); i++) {
        int count = 0;
        for (size_t j = i; j < scores.size() && scores[i].score == scores[j].score; j++)
            count++;
        rank += count - 1;
        for (size_t j = i; j < scores.size() && scores[i].score == scores[j].score; j++)
            scores[j].rank = rank;
        rank++;
        i += count - 1;
    }
    sort(scores.begin(), scores.end(), by_seq);
}

void dense_ranking(vector<Score>& scores) {
    sort(scores.begin(), scores.end(), rev_by_score);
    int rank = 1;
    for (size_t i = 0; i < scores.size(); i++) {
        int count = 0;
        for (size_t j = i; j < scores.size() && scores[i].score == scores[j].score; j++) {
            count++;
            scores[j].rank = rank;
        }
        rank++;
        i += count - 1;
    }
    sort(scores.begin(), scores.end(), by_seq);
}


int main(int argc, char* argv[]) {
    if (argc < 2) return EXIT_FAILURE;
    vector<Score> scores;
    for (int i = 1; i < argc; i++) {
        Score s;
        s.seq = i;
        s.score = atoi(argv[i]);
        s.rank = 0;
        scores.push_back(s);
    }

    cout << "Data:             ";
    for (size_t i = 0; i < scores.size(); i++) {
        cout << scores[i].score;
        if (i + 1 < scores.size())
            cout << ", ";
    }
    printf("\n");

    standard_ranking(scores);
    cout << "Standard ranking: ";
    for (size_t i = 0; i < scores.size(); i++) {
        cout << scores[i].rank;
        if (i + 1 < scores.size())
            cout << ", ";
    }
    cout << endl;

    modified_ranking(scores);
    cout << "Modified ranking: ";
    for (size_t i = 0; i < scores.size(); i++) {
        cout << scores[i].rank;
        if (i + 1 < scores.size())
            cout << ", ";
    }
    cout << endl;

    dense_ranking(scores);
    cout << "Dense ranking:    ";
    for (size_t i = 0; i < scores.size(); i++) {
        cout << scores[i].rank;
        if (i + 1 < scores.size())
            cout << ", ";
    }
    cout << endl;
}