Skip to content

Commit 4329c24

Browse files
committed
day 14 part 2; add notes to journal
1 parent 57a3cdf commit 4329c24

File tree

4 files changed

+110
-134
lines changed

4 files changed

+110
-134
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,22 @@ Day 23 was one of those problems where I took an entirely different approach in
125125
Usually when this happens, I "align" the two solutions so they re-use the same code. I started to do that
126126
after finishing part 2 but the approaches are so algorithmically different that I decided it wasn't worth
127127
the energy.
128+
129+
(time passes)
130+
131+
Well, I've finished a solid pass through all the problems. Here's what I need to return to:
132+
133+
```
134+
Day 14 part 2 = finding the christmas tree
135+
Day 17 part 2 = [quine](https://en.wikipedia.org/wiki/Quine_(computing))-ish problem
136+
Day 21 part 2 = keypad problem
137+
Day 24 part 2 = find 4 swaps of logic gates to make addition work
138+
```
139+
140+
I think I can do 14 and 21, if I put my mind to it. Honestly, I'm not sure about the other two.
141+
For those, I may ask my friend Rob who's also doing AoC this year, or look at reddit, instead of beating my
142+
head against a wall. Which I did for WEEKS for some problems during AoC 2018. Which was not healthy.
143+
144+
(more time passes)
145+
146+
Hey I figured out day 14!
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.codefork.aoc2024.day14;
2+
3+
import com.codefork.aoc2024.Problem;
4+
5+
import java.util.stream.Stream;
6+
7+
public class Part02 extends Problem {
8+
9+
public String solve(int width, int height, Stream<String> data) {
10+
// I tried a bunch of different strategies, including looking for unbalanced robot
11+
// counts in different quadrants, thinking that the quadrant stuff in part 1 was a hint.
12+
// I couldn't get that to work. after stepping away from it for over a week,
13+
// I thought to try a different approach: just look for clusters of adjacent robots,
14+
// since a picture is likely to have such clusters. at a low threshold, it displayed
15+
// a few false positives before yielding the answer, so it was just a matter of increasing
16+
// the threshold to something reasonable once I knew what the Christmas tree actually looked like.
17+
18+
System.out.println("This takes ~40 seconds");
19+
var swarm = Swarm.create(data, width, height);
20+
var keepGoing = true;
21+
var i = 0;
22+
while(keepGoing) {
23+
var newSwarm = swarm.doMoves(1);
24+
25+
var adjacentClusters = newSwarm.getAdjacentClusters();
26+
27+
var hasLines = adjacentClusters.stream().anyMatch(cluster ->
28+
cluster.size() > 20);
29+
30+
if(hasLines) {
31+
newSwarm.print();
32+
keepGoing = false;
33+
} else {
34+
swarm = newSwarm;
35+
i++;
36+
}
37+
}
38+
39+
return String.valueOf(i+1);
40+
}
41+
42+
@Override
43+
public String solve() {
44+
return solve(101, 103, getInput());
45+
}
46+
47+
public static void main(String[] args) {
48+
new Part02().run();
49+
}
50+
}

src/main/java/com/codefork/aoc2024/day14/Part02.java.bak

Lines changed: 0 additions & 83 deletions
This file was deleted.

src/main/java/com/codefork/aoc2024/day14/Swarm.java

Lines changed: 41 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
import com.codefork.aoc2024.util.Maps;
44

5+
import java.util.ArrayList;
6+
import java.util.HashSet;
57
import java.util.List;
68
import java.util.Map;
9+
import java.util.Set;
710
import java.util.regex.Pattern;
811
import java.util.stream.Collectors;
912
import java.util.stream.IntStream;
@@ -14,7 +17,11 @@
1417
public record Swarm(List<Robot> robots, int width, int height) {
1518

1619
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+
}
1825
}
1926

2027
public record Velocity(int dx, int dy) {
@@ -116,58 +123,41 @@ public Map<Integer, Integer> getQuadrantCounts() {
116123
));
117124
}
118125

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-
169126
public int getSafetyFactor() {
170127
return getQuadrantCounts().entrySet().stream()
171128
.reduce(1, (acc, entry) -> acc * entry.getValue(), Integer::sum);
172129
}
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+
173163
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy