Skip to content

Commit 7741221

Browse files
previous work
1 parent 5bd4c1c commit 7741221

File tree

2 files changed

+201
-14
lines changed
  • src/main/java/dev/jacobandersen/codechallenges

2 files changed

+201
-14
lines changed
Lines changed: 147 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,165 @@
11
package dev.jacobandersen.codechallenges.challenge.adventofcode.year2024.day15;
22

33
import dev.jacobandersen.codechallenges.challenge.adventofcode.Day;
4+
import dev.jacobandersen.codechallenges.util.Direction;
5+
import dev.jacobandersen.codechallenges.util.Grid;
6+
import dev.jacobandersen.codechallenges.util.Pair;
7+
8+
import java.util.ArrayList;
9+
import java.util.Arrays;
10+
import java.util.List;
11+
import java.util.concurrent.atomic.AtomicInteger;
412

513
public class Day15 extends Day {
14+
private static final String ROBOT = "@";
15+
private static final String CRATE = "O";
16+
private static final String BIG_CRATE_LEFT = "[";
17+
private static final String BIG_CRATE_RIGHT = "]";
18+
private static final String WALL = "#";
19+
private static final String FREE = ".";
20+
621
public Day15() {
722
super(2024, 15, "Warehouse Woes");
823
}
924

25+
private Pair<Grid<String>, String[]> loadInput() {
26+
final List<String> raw = getInputLines();
27+
final int blankIdx = raw.indexOf("");
28+
29+
return Pair.of(
30+
Grid.create(
31+
raw.subList(0, blankIdx).stream(),
32+
str -> new ArrayList<>(Arrays.stream(str.split("")).toList())
33+
).moveCellToFirstOccurrence(ROBOT),
34+
String.join("", raw.subList(blankIdx + 1, raw.size())).split("")
35+
);
36+
}
37+
38+
private Pair<Grid<String>, String[]> loadResizedInput() {
39+
var initial = loadInput();
40+
41+
Grid<String> resizedGrid = Grid.emptyGrid(initial.first().getRows(), initial.first().getCols() * 2, () -> ".");
42+
for (int row = 0; row < resizedGrid.getRows(); row++) {
43+
for (int initialCol = 0, col = 0; initialCol < initial.first().getCols() && col < resizedGrid.getCols(); initialCol++, col += 2) {
44+
final String initialValue = initial.first().get(row, initialCol);
45+
switch (initialValue) {
46+
case WALL -> {
47+
resizedGrid.set(row, col, WALL);
48+
resizedGrid.set(row, col + 1, WALL);
49+
}
50+
case FREE -> {
51+
resizedGrid.set(row, col, FREE);
52+
resizedGrid.set(row, col + 1, FREE);
53+
}
54+
case CRATE -> {
55+
resizedGrid.set(row, col, BIG_CRATE_LEFT);
56+
resizedGrid.set(row, col + 1, BIG_CRATE_RIGHT);
57+
}
58+
case ROBOT -> {
59+
resizedGrid.set(row, col, ROBOT);
60+
resizedGrid.set(row, col + 1, FREE);
61+
}
62+
}
63+
}
64+
}
65+
66+
return Pair.of(resizedGrid.moveCellToFirstOccurrence(ROBOT), initial.second());
67+
}
68+
69+
private boolean canPush(Grid<String> grid, Direction direction, boolean part2) {
70+
int steps = 0;
71+
boolean canPush = false;
72+
73+
while (grid.peek(direction).equals(CRATE)) {
74+
grid.move(direction);
75+
steps++;
76+
}
77+
78+
if (grid.peek(direction).equals(FREE)) {
79+
canPush = true;
80+
}
81+
82+
grid.move(direction.getOpposite(), steps);
83+
return canPush;
84+
}
85+
86+
private void pushCrates(Grid<String> grid, Direction direction, boolean part2) {
87+
int steps = 0;
88+
89+
while (grid.peek(direction).equals(CRATE)) {
90+
grid.move(direction);
91+
steps++;
92+
}
93+
94+
for (int i = 0; i < steps; i++) {
95+
grid.set(direction, CRATE);
96+
grid.set(FREE);
97+
grid.move(direction.getOpposite());
98+
}
99+
}
100+
101+
private void doMove(Grid<String> grid, Direction direction, boolean part2) {
102+
switch (grid.peek(direction)) {
103+
case WALL -> {
104+
}
105+
case FREE -> {
106+
grid.set(direction, ROBOT);
107+
grid.set(FREE);
108+
grid.move(direction);
109+
}
110+
case CRATE, BIG_CRATE_LEFT, BIG_CRATE_RIGHT -> {
111+
if (canPush(grid, direction, part2)) {
112+
pushCrates(grid, direction, part2);
113+
grid.set(direction, ROBOT);
114+
grid.set(FREE);
115+
grid.move(direction);
116+
}
117+
}
118+
}
119+
}
120+
121+
private int sumCrateGpsCoords(Grid<String> grid) {
122+
AtomicInteger sum = new AtomicInteger();
123+
grid.forEach(ctx -> {
124+
if (ctx.value().equals(CRATE)) {
125+
sum.addAndGet((100 * ctx.position().first()) + (ctx.position().second()));
126+
}
127+
});
128+
return sum.get();
129+
}
130+
131+
private List<Direction> translateInstructions(String[] instructions) {
132+
return Arrays.stream(instructions).map(inst -> switch(inst) {
133+
case "^":
134+
yield Direction.NORTH;
135+
case ">":
136+
yield Direction.EAST;
137+
case "v":
138+
yield Direction.SOUTH;
139+
case "<":
140+
yield Direction.WEST;
141+
default:
142+
throw new IllegalStateException("Unexpected instruction: " + inst);
143+
}).toList();
144+
}
145+
10146
@Override
11147
public String partOne() {
12-
getInputLines().forEach(System.out::println);
13-
return "";
148+
final var input = loadInput();
149+
150+
final var grid = input.first();
151+
translateInstructions(input.second()).forEach(inst -> doMove(grid, inst, false));
152+
153+
return String.valueOf(sumCrateGpsCoords(grid));
14154
}
15155

16156
@Override
17157
public String partTwo() {
158+
final var input = loadResizedInput();
159+
160+
final var grid = input.first();
161+
translateInstructions(input.second()).forEach(inst -> doMove(grid, inst, true));
162+
18163
return "";
19164
}
20165
}

src/main/java/dev/jacobandersen/codechallenges/util/Grid.java

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.jacobandersen.codechallenges.util;
22

3+
import java.lang.reflect.Array;
34
import java.util.ArrayList;
45
import java.util.List;
56
import java.util.function.Consumer;
@@ -76,6 +77,12 @@ public Grid<T> set(Pair<Integer, Integer> pos, T value) {
7677
return set(pos.first(), pos.second(), value);
7778
}
7879

80+
public Grid<T> set(Direction direction, T value) {
81+
Pair<Integer, Integer> rel = direction.relativeCoordinate();
82+
return set(currentRow + rel.first(), currentCol + rel.second(), value);
83+
}
84+
85+
7986
public Grid<T> set(int row, int col, T value) {
8087
grid.get(row).set(col, value);
8188
return this;
@@ -120,10 +127,27 @@ public T get(Pair<Integer, Integer> pos) {
120127
return get(pos.first(), pos.second());
121128
}
122129

130+
public T get(Direction direction) {
131+
Pair<Integer, Integer> rel = direction.relativeCoordinate();
132+
return get(currentRow + rel.first(), currentCol + rel.second());
133+
}
134+
123135
public T get(int row, int col) {
124136
return grid.get(row).get(col);
125137
}
126138

139+
public T peek(int row, int col) {
140+
if (row < 0 || row >= rows || col < 0 || col >= cols) {
141+
return null;
142+
}
143+
144+
return grid.get(row).get(col);
145+
}
146+
147+
public T peek(Pair<Integer, Integer> pos) {
148+
return peek(pos.first(), pos.second());
149+
}
150+
127151
public Grid<T> move(int row, int col) {
128152
if (row < 0 || row >= rows || col < 0 || col >= cols) {
129153
throw new IllegalArgumentException("Tried to move current cell beyond boundaries");
@@ -139,18 +163,6 @@ public Grid<T> move(Pair<Integer, Integer> pos) {
139163
return move(pos.first(), pos.second());
140164
}
141165

142-
public T peek(int row, int col) {
143-
if (row < 0 || row >= rows || col < 0 || col >= cols) {
144-
return null;
145-
}
146-
147-
return grid.get(row).get(col);
148-
}
149-
150-
public T peek(Pair<Integer, Integer> pos) {
151-
return peek(pos.first(), pos.second());
152-
}
153-
154166
public Grid<T> moveNorth() {
155167
move(currentRow - 1, currentCol);
156168
return this;
@@ -210,6 +222,13 @@ public Grid<T> move(Direction direction) {
210222
};
211223
}
212224

225+
public Grid<T> move(Direction direction, int times) {
226+
for (int i = 0; i < times; i++) {
227+
move(direction);
228+
}
229+
return this;
230+
}
231+
213232
public T peek(Direction direction) {
214233
return switch (direction) {
215234
case NORTH -> peekNorth();
@@ -220,6 +239,22 @@ public T peek(Direction direction) {
220239
};
221240
}
222241

242+
public T[] peek(Direction direction, int steps) {
243+
Pair<Integer, Integer> pos = getCurrentPos();
244+
245+
@SuppressWarnings("unchecked")
246+
final T[] out = (T[]) new Object[steps];
247+
248+
for (int i = 0; i < steps; i++) {
249+
T val = peek(direction);
250+
out[i] = val;
251+
if (val == null) break;
252+
}
253+
254+
move(pos);
255+
return out;
256+
}
257+
223258
public int[] peekPosition(Direction direction) {
224259
int[] position = new int[2];
225260
move(direction);
@@ -293,6 +328,13 @@ public List<List<T>> getBackingList() {
293328
return grid;
294329
}
295330

331+
public void printSimple() {
332+
getBackingList().forEach(lst -> {
333+
lst.forEach(System.out::print);
334+
System.out.println();
335+
});
336+
}
337+
296338
@Override
297339
public String toString() {
298340
StringBuilder builder = new StringBuilder("Grid {\n" +

0 commit comments

Comments
 (0)