aboutsummaryrefslogtreecommitdiff
path: root/2024/src/day13.cpp
diff options
context:
space:
mode:
Diffstat (limited to '2024/src/day13.cpp')
-rw-r--r--2024/src/day13.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/2024/src/day13.cpp b/2024/src/day13.cpp
new file mode 100644
index 0000000..9ba58ba
--- /dev/null
+++ b/2024/src/day13.cpp
@@ -0,0 +1,120 @@
1#include <array>
2#include <fstream>
3#include <iostream>
4#include <iterator>
5#include <numeric>
6#include <regex>
7#include <vector>
8using namespace std;
9
10vector<string>
11split(string_view line, string_view delimiter)
12{
13 string::size_type pos_start = 0;
14 string::size_type pos_end = 0;
15
16 vector<string> res;
17 while ( (pos_end = line.find(delimiter, pos_start)) != string::npos ) {
18 res.emplace_back(line.substr(pos_start, pos_end - pos_start));
19
20 pos_start = pos_end + delimiter.length();
21 }
22 if ( pos_start != line.size() ) {
23 res.emplace_back(line.substr(pos_start));
24 }
25 return res;
26}
27
28vector<array<long, 6>>
29read_file(string_view filename)
30{
31 static const regex pattern{ R"((\d+).*\+(\d+).*\+(\d+).*\+(\d+).*=(\d+).*=(\d+))" };
32
33 fstream input{ filename };
34 string content{ istreambuf_iterator<char>{ input }, {} };
35
36 auto parts = split(content, "\n\n");
37
38 vector<array<long, 6>> data;
39 for ( auto part: parts ) {
40 part.erase(std::remove(part.begin(), part.end(), '\n'), part.cend());
41
42 smatch matches;
43 if ( regex_search(part, matches, pattern) ) {
44 data.push_back({ stoi(matches[1]),
45 stoi(matches[2]),
46 stoi(matches[3]),
47 stoi(matches[4]),
48 stoi(matches[5]),
49 stoi(matches[6]) });
50 }
51 }
52
53 return data;
54}
55
56long
57test_brute_force(const array<long, 6>& machine)
58{
59 const auto button_a_x = machine[0];
60 const auto button_a_y = machine[1];
61 const auto button_b_x = machine[2];
62 const auto button_b_y = machine[3];
63 const auto price_x = machine[4];
64 const auto price_y = machine[5];
65
66 auto min_value = numeric_limits<long>::max();
67 for ( long i = 0; i != 100; ++i ) {
68 for ( long j = 0; j != 100; ++j ) {
69 if ( i * button_a_x + j * button_b_x == price_x &&
70 i * button_a_y + j * button_b_y == price_y ) {
71 min_value = min(min_value, i * 3 + j);
72 }
73 }
74 }
75 return min_value != numeric_limits<long>::max() ? min_value : 0;
76}
77
78long
79test_algorithmic(const array<long, 6>& machine)
80{
81 const auto button_a_x = machine[0];
82 const auto button_a_y = machine[1];
83 const auto button_b_x = machine[2];
84 const auto button_b_y = machine[3];
85 const auto price_x = machine[4] + 10000000000000;
86 const auto price_y = machine[5] + 10000000000000;
87
88 const auto i = (price_x * button_b_y - price_y * button_b_x) / (button_a_x * button_b_y - button_a_y * button_b_x);
89 const auto j = (price_x - button_a_x * i) / button_b_x;
90
91 if ( i * button_a_x + j * button_b_x == price_x &&
92 i * button_a_y + j * button_b_y == price_y ) {
93 return i * 3 + j;
94 }
95 return 0;
96}
97
98void
99part1(const vector<array<long, 6>>& machines)
100{
101 cout << accumulate(machines.begin(), machines.end(), 0L, [](auto init, const auto& machine) {
102 return init + test_brute_force(machine);
103 }) << endl;
104}
105
106void
107part2(const vector<array<long, 6>>& machines)
108{
109 cout << accumulate(machines.begin(), machines.end(), 0L, [](auto init, const auto& machine) {
110 return init + test_algorithmic(machine);
111 }) << endl;
112}
113
114int
115main()
116{
117 auto data = read_file("data/day13.txt");
118 part1(data);
119 part2(data);
120}