Skip to content

Commit d2c754e

Browse files
committed
Add year 2021 day21
1 parent a0a9a87 commit d2c754e

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package dev.linl33.adventofcode.year2021;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
5+
import java.io.BufferedReader;
6+
import java.io.IOException;
7+
import java.util.ArrayDeque;
8+
import java.util.ArrayList;
9+
import java.util.Arrays;
10+
import java.util.List;
11+
12+
public class Day21 extends AdventSolution2021<Integer, Long> {
13+
private static final int P1_WINNING_SCORE = 1000;
14+
private static final int P2_WINNING_SCORE = 21;
15+
private static final int[] MOVES_TO_U = new int[] { 0, 0, 0, 1, 3, 6, 7, 6, 3, 1 };
16+
17+
public static void main(String[] args) {
18+
new Day21().runAndPrintAll();
19+
}
20+
21+
@Override
22+
public Integer part1(@NotNull BufferedReader reader) throws IOException {
23+
var p1Line = reader.readLine();
24+
var p2Line = reader.readLine();
25+
26+
var pos = new int[] {
27+
Integer.parseInt(p1Line, 28, p1Line.length(), 10),
28+
Integer.parseInt(p2Line, 28, p2Line.length(), 10),
29+
};
30+
31+
var scores = new int[2];
32+
33+
var moves = -3;
34+
var player = 0;
35+
while (scores[0] < P1_WINNING_SCORE && scores[1] < P1_WINNING_SCORE) {
36+
moves += 9;
37+
movePlayer(pos, scores, player, moves);
38+
39+
player = 1 - player;
40+
}
41+
42+
return scores[player] * ((moves + 3) / 9) * 3;
43+
}
44+
45+
@Override
46+
public Long part2(@NotNull BufferedReader reader) throws IOException {
47+
var p1Line = reader.readLine();
48+
var p2Line = reader.readLine();
49+
50+
var nullPos = new int[] {
51+
Integer.parseInt(p1Line, 28, p1Line.length(), 10),
52+
Integer.parseInt(p2Line, 28, p2Line.length(), 10),
53+
};
54+
55+
var universes = new long[2];
56+
57+
// TODO: make this run faster
58+
var stack = new ArrayDeque<List<Integer>>();
59+
for (int i = 9; i >= 3; i--) {
60+
stack.push(List.of(i));
61+
}
62+
63+
while (!stack.isEmpty()) {
64+
var next = stack.pop();
65+
66+
var pos = Arrays.copyOf(nullPos, 2);
67+
var scores = new int[2];
68+
var player = 0;
69+
70+
for (int moves : next) {
71+
movePlayer(pos, scores, player, moves);
72+
player = 1 - player;
73+
}
74+
75+
if (scores[0] >= P2_WINNING_SCORE || scores[1] >= P2_WINNING_SCORE) {
76+
var uTally = 1L;
77+
78+
for (int moves : next) {
79+
uTally *= MOVES_TO_U[moves];
80+
}
81+
82+
if (scores[0] >= P2_WINNING_SCORE) {
83+
universes[0] += uTally;
84+
} else {
85+
universes[1] += uTally;
86+
}
87+
} else {
88+
for (int i = 9; i >= 3; i--) {
89+
var nextMoves = new ArrayList<>(next);
90+
nextMoves.add(i);
91+
stack.push(nextMoves);
92+
}
93+
}
94+
}
95+
96+
return Math.max(universes[0], universes[1]);
97+
}
98+
99+
private static void movePlayer(@NotNull int[] pawnPositions, @NotNull int[] scores, int player, int moves) {
100+
var newPos = ((pawnPositions[player] + moves - 1) % 10) + 1;
101+
pawnPositions[player] = newPos;
102+
scores[player] += newPos;
103+
}
104+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Player 1 starting position: 8
2+
Player 2 starting position: 10
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Player 1 starting position: 4
2+
Player 2 starting position: 8
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package dev.linl33.adventofcode.year2021.test;
2+
3+
import dev.linl33.adventofcode.lib.solution.AdventSolution;
4+
import dev.linl33.adventofcode.testlib.AdventSolutionTest;
5+
import dev.linl33.adventofcode.year2021.Day20;
6+
import dev.linl33.adventofcode.year2021.Day21;
7+
8+
import java.util.Map;
9+
10+
class Day21Test implements AdventSolutionTest<Integer, Long> {
11+
@Override
12+
public AdventSolution<Integer, Long> newSolutionInstance() {
13+
return new Day21();
14+
}
15+
16+
@Override
17+
public Map<Object, Integer> getPart1Cases() {
18+
return Map.of(
19+
newSolutionInstance().getPart1Resource(), 605070,
20+
"day21test1", 739785
21+
);
22+
}
23+
24+
@Override
25+
public Map<Object, Long> getPart2Cases() {
26+
return Map.of(
27+
newSolutionInstance().getPart2Resource(), 218433063958910L,
28+
"day21test1", 444356092776315L
29+
);
30+
}
31+
}

0 commit comments

Comments
 (0)