aboutsummaryrefslogtreecommitdiff
path: root/2017/src/day22.cpp
diff options
context:
space:
mode:
Diffstat (limited to '2017/src/day22.cpp')
-rw-r--r--2017/src/day22.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/2017/src/day22.cpp b/2017/src/day22.cpp
new file mode 100644
index 0000000..2567fb1
--- /dev/null
+++ b/2017/src/day22.cpp
@@ -0,0 +1,158 @@
1#include <filesystem>
2#include <fstream>
3#include <iostream>
4#include <map>
5#include <set>
6#include <string>
7#include <tuple>
8
9using namespace std;
10
11namespace {
12
13set<tuple<int, int>>
14read_file(const filesystem::path& filename)
15{
16 ifstream file{ filename };
17 set<tuple<int, int>> data;
18
19 int row = 0;
20 for ( string line; getline(file, line); ) {
21 int col = 0;
22
23 for ( char chr: line ) {
24 if ( chr == '#' ) {
25 data.emplace(col, row);
26 }
27 ++col;
28 }
29
30 ++row;
31 }
32
33 return data;
34}
35
36#if 0
37void
38print(const set<tuple<int, int>>& grid, tuple<int, int> pos)
39{
40 for ( int y = -5; y < 5; ++y ) {
41 for ( int x = -5; x < 5; ++x ) {
42 auto coord = make_tuple(x, y);
43
44 if ( pos == coord ) {
45 cout << '[';
46 }
47 else {
48 cout << ' ';
49 }
50
51 auto chr = grid.contains(coord) ? '#' : '.';
52 cout << chr;
53
54 if ( pos == coord ) {
55 cout << ']';
56 }
57 else {
58 cout << ' ';
59 }
60 }
61 cout << '\n';
62 }
63 cout << '\n';
64}
65#endif
66
67void
68part1(set<tuple<int, int>> grid, tuple<int, int> pos)
69{
70 const array<tuple<int, int>, 4> dirs{
71 make_tuple(-1, 0),
72 make_tuple(0, -1),
73 make_tuple(1, 0),
74 make_tuple(0, 1)
75 };
76 unsigned dir = 1; // up
77
78 int infections = 0;
79 for ( int i = 0; i != 10000; ++i ) {
80 if ( grid.contains(pos) ) {
81 dir = (dir + 1) % 4;
82 grid.erase(pos);
83 }
84 else {
85 dir = (dir + 3) % 4;
86 grid.insert(pos);
87 ++infections;
88 }
89
90 auto [dx, dy] = dirs.at(dir);
91 get<0>(pos) += dx;
92 get<1>(pos) += dy;
93 }
94 cout << "Part1: " << infections << '\n';
95}
96
97void
98part2(set<tuple<int, int>> grid, tuple<int, int> pos)
99{
100 const array<tuple<int, int>, 4> dirs{
101 make_tuple(-1, 0),
102 make_tuple(0, -1),
103 make_tuple(1, 0),
104 make_tuple(0, 1)
105 };
106 unsigned dir = 1; // up
107
108 static const int weak = 0;
109 static const int infected = 1;
110 static const int flagged = 2;
111
112 map<tuple<int, int>, int> grid_;
113 for ( const auto& value: grid ) {
114 grid_[value] = infected;
115 }
116
117 int infections = 0;
118 for ( int i = 0; i != 10000000; ++i ) {
119 if ( !grid_.contains(pos) ) {
120 grid_[pos] = weak;
121 dir = (dir + 3) % 4;
122 }
123 else {
124 switch ( grid_[pos] ) {
125 case weak:
126 grid_[pos] = infected;
127 ++infections;
128 break;
129 case infected:
130 grid_[pos] = flagged;
131 dir = (dir + 1) % 4;
132 break;
133 case flagged:
134 grid_.erase(pos);
135 dir = (dir + 2) % 4;
136 break;
137 default:
138 cerr << "Wrong state!!" << '\n';
139 return;
140 }
141 }
142
143 auto [dx, dy] = dirs.at(dir);
144 get<0>(pos) += dx;
145 get<1>(pos) += dy;
146 }
147 cout << "Part2: " << infections << '\n';
148}
149
150} // namespace
151
152int
153main()
154{
155 auto grid = read_file("data/day22.txt");
156 part1(grid, { 12, 12 });
157 part2(grid, { 12, 12 });
158}