8
8
#ifndef DAY14_HPP_5W9MWUPG
9
9
#define DAY14_HPP_5W9MWUPG
10
10
11
- #include " lib.hpp" // for Pos, Delta, expect_input
12
- #include < array> // for array
13
- #include < iostream> // for istream
14
- #include < string> // for string, getline
15
- #include < utility> // for move
16
- #include < vector> // for vector
11
+ #include " ds/grid.hpp" // for Grid
12
+ #include " lib.hpp" // for Pos, Delta, expect_input, DIRECTIONS
13
+ #include < algorithm> // for max_element
14
+ #include < array> // for array
15
+ #include < iostream> // for istream, ostream, noskipws, ws
16
+ #include < utility> // for move
17
+ #include < vector> // for vector
18
+ // IWYU pragma: no_include <initializer_list> // for DIRECTIONS
17
19
18
20
namespace aoc ::day14 {
19
21
@@ -33,15 +35,6 @@ std::istream &operator>>(std::istream &is, Robot &robot) {
33
35
return is;
34
36
}
35
37
36
- auto read_input (std::istream &is) {
37
- Robot robot;
38
- std::vector<Robot> robots;
39
- while (is >> robot) {
40
- robots.push_back (std::move (robot));
41
- }
42
- return robots;
43
- }
44
-
45
38
void Robot::update (const Pos &bounds) {
46
39
pos += vel;
47
40
if (pos.x < 0 ) {
@@ -56,7 +49,43 @@ void Robot::update(const Pos &bounds) {
56
49
}
57
50
}
58
51
59
- int safety_factor (const std::vector<Robot> &robots, const Pos &bounds) {
52
+ class Robots {
53
+ std::vector<Robot> robots;
54
+ Pos bounds;
55
+
56
+ aoc::ds::Grid<int > robot_counts;
57
+
58
+ explicit Robots (const Pos &bounds)
59
+ : robots(), bounds(bounds), robot_counts(bounds.x, bounds.y, 0 ) {}
60
+
61
+ public:
62
+ static Robots read (std::istream &is, const Pos &bounds);
63
+ void update ();
64
+ int safety_factor () const ;
65
+ int largest_clump () const ;
66
+
67
+ friend std::ostream &operator <<(std::ostream &os, const Robots &robots);
68
+ };
69
+
70
+ Robots Robots::read (std::istream &is, const Pos &bounds) {
71
+ Robot robot;
72
+ Robots robots (bounds);
73
+ while (is >> robot) {
74
+ ++robots.robot_counts [robot.pos ];
75
+ robots.robots .push_back (std::move (robot));
76
+ }
77
+ return robots;
78
+ }
79
+
80
+ void Robots::update () {
81
+ for (auto &robot : robots) {
82
+ --robot_counts[robot.pos ];
83
+ robot.update (bounds);
84
+ ++robot_counts[robot.pos ];
85
+ }
86
+ }
87
+
88
+ int Robots::safety_factor () const {
60
89
std::array<int , 4 > quadrants{};
61
90
for (const auto &robot : robots) {
62
91
int quad_idx = 0 ;
@@ -77,6 +106,53 @@ int safety_factor(const std::vector<Robot> &robots, const Pos &bounds) {
77
106
return quadrants[0 ] * quadrants[1 ] * quadrants[2 ] * quadrants[3 ];
78
107
}
79
108
109
+ int Robots::largest_clump () const {
110
+ std::vector<int > clumps;
111
+ aoc::ds::Grid<int > clump_indices (robot_counts, -1 );
112
+ for (const Robot &robot : robots) {
113
+ // This isn't actually correct, and mislabels shapes with indents like
114
+ // ..##
115
+ // .##.
116
+ // but it's good enough to find a Christmas tree. See day 12 for a
117
+ // proper (and slower) implementation.
118
+ if (clump_indices[robot.pos ] == -1 ) {
119
+ for (const auto &dir : DIRECTIONS) {
120
+ Pos neighbor = robot.pos + aoc::Delta (dir, true );
121
+ if (robot_counts.in_bounds (neighbor) &&
122
+ robot_counts[neighbor] > 0 ) {
123
+ if (clump_indices[neighbor] != -1 ) {
124
+ clump_indices[robot.pos ] = clump_indices[neighbor];
125
+ ++clumps[clump_indices[robot.pos ]];
126
+ break ;
127
+ }
128
+ }
129
+ }
130
+ if (clump_indices[robot.pos ] == -1 ) {
131
+ // new clump
132
+ clump_indices[robot.pos ] = clumps.size ();
133
+ clumps.push_back (1 );
134
+ }
135
+ }
136
+ }
137
+ return *std::max_element (clumps.begin (), clumps.end ());
138
+ }
139
+
140
+ std::ostream &operator <<(std::ostream &os, const Robots &robots) {
141
+ for (const auto &row : robots.robot_counts ) {
142
+ for (const auto &count : row) {
143
+ if (count == 0 ) {
144
+ os << ' ' ;
145
+ } else if (count < 10 ) {
146
+ os << count;
147
+ } else {
148
+ os << ' *' ;
149
+ }
150
+ }
151
+ os << " \n " ;
152
+ }
153
+ return os;
154
+ }
155
+
80
156
} // namespace aoc::day14
81
157
82
158
#endif /* end of include guard: DAY14_HPP_5W9MWUPG */
0 commit comments