-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_11.cpp
119 lines (102 loc) · 3.11 KB
/
day_11.cpp
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
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
#include <memory>
#include "data/data_day_11.h"
constexpr int MAX_ENERGY = 9;
constexpr int GRID_SIZE = 10;
constexpr int ITERATIONS = 100;
int char_to_int(char c)
{
return c - '0';
}
class Octopus
{
public:
Octopus(int start_energy) : _energy(start_energy), _flashed(false) {}
void add_neighbour(Octopus* neighbour)
{
_neighbours.push_back(neighbour);
}
void tick()
{
if (!_flashed && ++_energy > MAX_ENERGY)
_flash();
}
bool has_flashed(bool reset)
{
bool flashed = _flashed;
if (reset)
_flashed = false;
return flashed;
}
private:
void _flash()
{
_flashed = true;
_energy = 0;
std::for_each(_neighbours.begin(), _neighbours.end(), [] (auto& a) {a->tick();});
}
int _energy;
bool _flashed;
std::vector<Octopus*> _neighbours;
};
void add_neighbours(std::vector<std::unique_ptr<Octopus>>& octas)
{
for (int y = 0; y < GRID_SIZE; ++y)
{
for (int x = 0; x < GRID_SIZE; ++x)
{
// Add neighbouring octopuses clock-wise, starting at 12 o clock.
Octopus* octopus = octas.at(x + GRID_SIZE * y).get();
if (y > 0)
octopus->add_neighbour(octas.at(GRID_SIZE * (y - 1) + x).get());
if (x < GRID_SIZE - 1 && y > 0)
octopus->add_neighbour(octas.at(GRID_SIZE * (y - 1) + x + 1).get());
if (x < GRID_SIZE - 1)
octopus->add_neighbour(octas.at(GRID_SIZE * y + x + 1).get());
if (x < GRID_SIZE - 1 && y < GRID_SIZE - 1)
octopus->add_neighbour(octas.at(GRID_SIZE * (y + 1) + x + 1).get());
if (y < GRID_SIZE - 1)
octopus->add_neighbour(octas.at(GRID_SIZE * (y + 1) + x).get());
if (x > 0 && y < GRID_SIZE - 1)
octopus->add_neighbour(octas.at(GRID_SIZE * (y + 1) + x - 1).get());
if (x > 0)
octopus->add_neighbour(octas.at(GRID_SIZE * y + x - 1).get());
if (x > 0 && y > 0)
octopus->add_neighbour(octas.at(GRID_SIZE * (y - 1) + x - 1).get());
}
}
}
void solve_day_11()
{
std::vector<std::unique_ptr<Octopus>> octas;
for (auto c : std::string_view(DATA_11_12))
{
octas.push_back(std::make_unique<Octopus>(char_to_int(c)));
}
add_neighbours(octas);
int total_flashes = 0;
int iters = 0;
while(++iters)
{
std::for_each(octas.begin(), octas.end(), [] (auto& a) {a->tick();});
int flashes = std::accumulate(octas.begin(), octas.end(), 0, [] (auto a, auto& b) {return a + (b->has_flashed(true)? 1 : 0);});
total_flashes += flashes;
if (iters == ITERATIONS)
{
std::cout << "Total flashes after " << iters << " iterations: " << total_flashes << std::endl;
}
if (flashes == octas.size())
{
break;
}
}
std::cout << "All octopuses flashed at iteration: " << iters << std::endl;
}
int main()
{
solve_day_11();
return 0;
}