summaryrefslogtreecommitdiff
path: root/2023/07/src/part1.cpp
blob: 089be93a3e0a9e6a2dd9b8e5d277570108f54da0 (plain) (blame)
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
#include <algorithm>
#include <array>
#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <string>

class Hand
{
    static constexpr int HAND{ 5 };

    int bet_;
    int score_{};
    std::array<char,HAND> cards_;

public:
    Hand(const std::string& cards, int bet) : bet_{ bet }
    {
        for (int c = 0; c < HAND; ++c)
        {
            switch (cards[c])
            {
                case 'A':
                    cards_[c] = 12;
                    break;
                case 'K':
                    cards_[c] = 11;
                    break;
                case 'Q':
                    cards_[c] = 10;
                    break;
                case 'J':
                    cards_[c] = 9;
                    break;
                case 'T':
                    cards_[c] = 8;
                    break;
                default:
                    cards_[c] = cards[c] - '2';
            }
        }
    
        std::array<int,13> mult{};
        std::for_each(cards_.begin(), cards_.end(), [&mult](int c) { ++mult[c]; });
        std::for_each(mult.begin(), mult.end(), [this](int c) {
            switch (c)
            {
                case 2:
                    this->score_ += 1;
                    break;
                case 3:
                    this->score_ += 3;
                    break;
                case 4:
                    this->score_ += 5;
                    break;
                case 5:
                    this->score_ += 6;
                    break;
            }
        });
    }

    inline int bet() const
    {
        return bet_;
    }

    bool operator<(const Hand& that) const
    {
        return this->score_ < that.score_ or
               (this->score_ == that.score_ and this->cards_ < that.cards_);
    }

    static Hand from_string(const std::string& str)
    {
        int bet;
        std::string hand;
        std::istringstream{ str } >> hand >> bet;
        return { hand, bet };
    }
};

int main(void)
{
    int answer{};
    std::multiset<Hand> hands;

    std::ifstream input{ "resources/input.txt" };
    if (input.is_open())
    {
        std::string line;
        while (not std::getline(input,line).eof())
        {
            hands.insert(Hand::from_string(line));
        }
    }
    input.close();

    int rank{};
    for (const auto& h : hands)
    {
        answer += ++rank * h.bet();
    }

    std::cout << answer << std::endl;
    return 0;
}