aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--makefile3
-rw-r--r--src/day07.cpp189
2 files changed, 191 insertions, 1 deletions
diff --git a/makefile b/makefile
index 298d71e..e9394b6 100644
--- a/makefile
+++ b/makefile
@@ -5,7 +5,8 @@ all: bin/day01 \
5 bin/day03 \ 5 bin/day03 \
6 bin/day04 \ 6 bin/day04 \
7 bin/day05 \ 7 bin/day05 \
8 bin/day06 8 bin/day06 \
9 bin/day07
9 10
10bin: 11bin:
11 mkdir $@ 12 mkdir $@
diff --git a/src/day07.cpp b/src/day07.cpp
new file mode 100644
index 0000000..1f44ac5
--- /dev/null
+++ b/src/day07.cpp
@@ -0,0 +1,189 @@
1#include <algorithm>
2#include <cassert>
3#include <fstream>
4#include <iostream>
5#include <map>
6#include <sstream>
7#include <tuple>
8#include <vector>
9using namespace std;
10
11enum kind_type {
12 five_kind,
13 four_kind,
14 full_house_kind,
15 three_kind,
16 two_pair_kind,
17 one_pair_kind,
18 high_card_kind
19};
20
21kind_type
22kind1(string hand)
23{
24 map<char, size_t> mapping{};
25
26 for ( auto chr: hand ) {
27 ++mapping[chr];
28 }
29
30 sort(hand.begin(), hand.end());
31 hand.erase(unique(hand.begin(), hand.end()), hand.end());
32
33 if ( mapping.size() == 1 ) {
34 return five_kind;
35 }
36 if ( mapping.size() == 2 ) {
37 if ( mapping[hand[0]] == 4 || mapping[hand[1]] == 4 ) {
38 return four_kind;
39 }
40 return full_house_kind;
41 }
42 if ( mapping.size() == 3 ) {
43 if ( mapping[hand[0]] == 3 || mapping[hand[1]] == 3 || mapping[hand[2]] == 3 ) {
44 return three_kind;
45 }
46 return two_pair_kind;
47 }
48 if ( mapping.size() == 4 ) {
49 return one_pair_kind;
50 }
51
52 return high_card_kind;
53}
54
55kind_type
56kind2(const string& hand)
57{
58 map<char, size_t> mapping{};
59
60 for ( auto chr: hand ) {
61 ++mapping[chr];
62 }
63
64 auto joker_amount = mapping['J'];
65 mapping.erase('J');
66
67 vector<size_t> amounts{};
68 amounts.reserve(mapping.size());
69 for ( const auto& entry: mapping ) {
70 amounts.emplace_back(entry.second);
71 }
72
73 sort(amounts.begin(), amounts.end(), greater<>());
74 if ( amounts.empty() ) {
75 amounts.emplace_back(joker_amount);
76 }
77 else {
78 amounts[0] += joker_amount;
79 }
80
81 if ( amounts[0] == 5 ) {
82 return five_kind;
83 }
84 if ( amounts[0] == 4 ) {
85 return four_kind;
86 }
87 if ( amounts[0] == 3 and amounts[1] == 2 ) {
88 return full_house_kind;
89 }
90 if ( amounts[0] == 3 ) {
91 return three_kind;
92 }
93 if ( amounts[0] == 2 && amounts[1] == 2 ) {
94 return two_pair_kind;
95 }
96 if ( amounts[0] == 2 ) {
97 return one_pair_kind;
98 }
99
100 return high_card_kind;
101}
102
103void
104solve(const function<kind_type(string)>& kind, map<char, int> weights)
105{
106 fstream input{ "data/day07.txt" };
107 vector<tuple<string, kind_type, long>> values{};
108
109 string hand;
110 long bid = 0;
111 while ( input >> hand >> bid ) {
112 values.emplace_back(hand, kind(hand), bid);
113 }
114
115 sort(values.begin(), values.end(), [&](const tuple<string, kind_type, long>& first, const tuple<string, kind_type, long>& second) {
116 const auto& first_hand = get<0>(first);
117 const auto& second_hand = get<0>(second);
118
119 auto first_kind = get<1>(first);
120 auto second_kind = get<1>(second);
121
122 if ( first_kind == second_kind ) {
123 for ( size_t idx = 0; idx != 5; ++idx ) {
124 const auto first_weight = weights[first_hand[idx]];
125 const auto second_weight = weights[second_hand[idx]];
126
127 if ( first_weight != second_weight ) {
128 return first_weight < second_weight;
129 }
130 }
131 }
132 return first_kind > second_kind;
133 });
134
135 long total = 0;
136 long rank = 1;
137 for ( const auto& value: values ) {
138 total += rank * get<2>(value);
139 ++rank;
140 }
141 cout << total << endl;
142}
143
144int
145main()
146{
147 assert(kind1("AAAAA") == five_kind);
148 assert(kind1("AA8AA") == four_kind);
149 assert(kind1("23332") == full_house_kind);
150 assert(kind1("TTT98") == three_kind);
151 assert(kind1("23432") == two_pair_kind);
152 assert(kind1("A23A4") == one_pair_kind);
153 assert(kind1("23456") == high_card_kind);
154
155 map<char, int> weights1 = {
156 { '2', 2 },
157 { '3', 3 },
158 { '4', 4 },
159 { '5', 5 },
160 { '6', 6 },
161 { '7', 7 },
162 { '8', 8 },
163 { '9', 9 },
164 { 'T', 10 },
165 { 'J', 11 },
166 { 'Q', 12 },
167 { 'K', 13 },
168 { 'A', 14 },
169 };
170
171 map<char, int> weights2 = {
172 { 'J', 1 },
173 { '2', 2 },
174 { '3', 3 },
175 { '4', 4 },
176 { '5', 5 },
177 { '6', 6 },
178 { '7', 7 },
179 { '8', 8 },
180 { '9', 9 },
181 { 'T', 10 },
182 { 'Q', 11 },
183 { 'K', 12 },
184 { 'A', 13 },
185 };
186
187 solve(kind1, weights1);
188 solve(kind2, weights2);
189}