|
2 | 2 |
|
3 | 3 | import com.codefork.aoc2024.util.Maps;
|
4 | 4 |
|
| 5 | +import java.util.ArrayList; |
| 6 | +import java.util.HashSet; |
5 | 7 | import java.util.List;
|
6 | 8 | import java.util.Map;
|
| 9 | +import java.util.Set; |
7 | 10 | import java.util.regex.Pattern;
|
8 | 11 | import java.util.stream.Collectors;
|
9 | 12 | import java.util.stream.IntStream;
|
|
14 | 17 | public record Swarm(List<Robot> robots, int width, int height) {
|
15 | 18 |
|
16 | 19 | public record Position(int x, int y) {
|
17 |
| - |
| 20 | + public boolean isAdjacent(Position other) { |
| 21 | + var xDiff = Math.abs(other.x() - x); |
| 22 | + var yDiff = Math.abs(other.y() - y); |
| 23 | + return xDiff + yDiff <= 1; |
| 24 | + } |
18 | 25 | }
|
19 | 26 |
|
20 | 27 | public record Velocity(int dx, int dy) {
|
@@ -116,58 +123,41 @@ public Map<Integer, Integer> getQuadrantCounts() {
|
116 | 123 | ));
|
117 | 124 | }
|
118 | 125 |
|
119 |
| - /** |
120 |
| - * testing for part 2: try smaller sections |
121 |
| - */ |
122 |
| - public Map<Integer, Integer> getCustomSectionCounts() { |
123 |
| - var byQuadrant = robots.stream() |
124 |
| - .collect(Collectors.groupingBy( |
125 |
| - (robot) -> { |
126 |
| - if (robot.position().y() < height / 3) { |
127 |
| - if (robot.position().x() < width / 2) { |
128 |
| - return 0; |
129 |
| - } else if (robot.position().x() > width / 2) { |
130 |
| - return 1; |
131 |
| - } |
132 |
| - } else if (robot.position().y() > height / 3 && robot.position().y() < (height / 3) * 2) { |
133 |
| - if (robot.position().x() < width / 2) { |
134 |
| - return 2; |
135 |
| - } else if (robot.position().x() > width / 2) { |
136 |
| - return 3; |
137 |
| - } |
138 |
| - } else if (robot.position().y() > (height / 3) * 2) { |
139 |
| - if (robot.position().x() < width / 2) { |
140 |
| - return 4; |
141 |
| - } else if (robot.position().x() > width / 2) { |
142 |
| - return 5; |
143 |
| - } |
144 |
| - } |
145 |
| - // put the robots on the center lines in a separate group |
146 |
| - // that we'll discard |
147 |
| - return DISCARD; |
148 |
| - }) |
149 |
| - ); |
150 |
| - return byQuadrant.entrySet().stream() |
151 |
| - .filter(entry -> entry.getKey() != DISCARD) |
152 |
| - .collect(Collectors.toMap( |
153 |
| - Map.Entry::getKey, |
154 |
| - entry -> { |
155 |
| - // count occupied positions rather than robots, since they can be stacked, and we only |
156 |
| - // care about what they look like from above |
157 |
| - record Pos(int x, int y) { |
158 |
| - } |
159 |
| - var list = entry.getValue(); |
160 |
| - var occupiedPositions = list.stream() |
161 |
| - .map(robot -> new Pos(robot.position().x(), robot.position().y())) |
162 |
| - .collect(Collectors.toSet()); |
163 |
| - return occupiedPositions.size(); |
164 |
| - }, |
165 |
| - Integer::sum |
166 |
| - )); |
167 |
| - } |
168 |
| - |
169 | 126 | public int getSafetyFactor() {
|
170 | 127 | return getQuadrantCounts().entrySet().stream()
|
171 | 128 | .reduce(1, (acc, entry) -> acc * entry.getValue(), Integer::sum);
|
172 | 129 | }
|
| 130 | + |
| 131 | + /** |
| 132 | + * Look for groups of adjacent robots. this returns a list of sets of positions, not |
| 133 | + * the Robots themselves, because we only care about positions. We actually only care about the |
| 134 | + * existence of clusters, not even the positions. |
| 135 | + */ |
| 136 | + public List<Set<Position>> getAdjacentClusters() { |
| 137 | + var clusters = new ArrayList<Set<Position>>(); |
| 138 | + for(var robot : robots()) { |
| 139 | + var position = robot.position(); |
| 140 | + |
| 141 | + var newClusters = new ArrayList<Set<Swarm.Position>>(); |
| 142 | + |
| 143 | + var mergedCluster = new HashSet<Position>(); |
| 144 | + for(var cluster : clusters) { |
| 145 | + var belongs = cluster.stream().anyMatch(p -> p.isAdjacent(position)); |
| 146 | + if(belongs) { |
| 147 | + mergedCluster.addAll(cluster); |
| 148 | + mergedCluster.add(position); |
| 149 | + } else { |
| 150 | + newClusters.add(cluster); |
| 151 | + } |
| 152 | + } |
| 153 | + if(mergedCluster.isEmpty()) { |
| 154 | + mergedCluster.add(position); |
| 155 | + } |
| 156 | + newClusters.add(mergedCluster); |
| 157 | + |
| 158 | + clusters = newClusters; |
| 159 | + } |
| 160 | + return clusters; |
| 161 | + } |
| 162 | + |
173 | 163 | }
|
0 commit comments