Skip to content

Commit 647ebc7

Browse files
committed
Day 22
1 parent 38d0987 commit 647ebc7

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

src/test/java/com/macasaet/Day22.java

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package com.macasaet;
2+
3+
import java.io.IOException;
4+
import java.util.HashSet;
5+
import java.util.LinkedList;
6+
import java.util.List;
7+
import java.util.Objects;
8+
import java.util.stream.Collectors;
9+
import java.util.stream.StreamSupport;
10+
11+
public class Day22 {
12+
13+
public static void main(final String[] args) throws IOException {
14+
try (var spliterator = new LineSpliterator(Day22.class.getResourceAsStream("/day-22-input.txt"))) {
15+
final var lines = StreamSupport.stream(spliterator, false)
16+
.collect(Collectors.toUnmodifiableList());
17+
18+
final var player1cards = new LinkedList<Integer>();
19+
final var player2cards = new LinkedList<Integer>();
20+
var target = player1cards;
21+
for (final var line : lines) {
22+
if (line.isBlank()) {
23+
target = player2cards;
24+
}
25+
if (line.matches("^[0-9]+$")) {
26+
target.add(Integer.parseInt(line));
27+
}
28+
}
29+
var player1 = new Player(1, new LinkedList<>(player1cards));
30+
var player2 = new Player(2, new LinkedList<>(player2cards));
31+
32+
// Part 1
33+
while (player1.hasCards() && player2.hasCards()) {
34+
final int p1 = player1.drawTop();
35+
final int p2 = player2.drawTop();
36+
if (p1 > p2) {
37+
player1.addToBottom(p1);
38+
player1.addToBottom(p2);
39+
} else {
40+
player2.addToBottom(p2);
41+
player2.addToBottom(p1);
42+
}
43+
}
44+
var winner = player1cards.isEmpty() ? player2 : player1;
45+
System.out.println("Part 1: " + winner.score());
46+
47+
// Part 2
48+
player1 = new Player(1, new LinkedList<>(player1cards));
49+
player2 = new Player(2, new LinkedList<>(player2cards));
50+
winner = playGame(player1, player2);
51+
System.out.println("Part 2: " + winner.score());
52+
}
53+
}
54+
55+
protected static Player playGame(final Player player1, final Player player2) {
56+
final var rounds = new HashSet<>();
57+
while (player1.hasCards() && player2.hasCards()) {
58+
final var round = new Round(player1, player2);
59+
if (rounds.contains(round)) {
60+
return player1;
61+
}
62+
rounds.add(round);
63+
final int p1 = player1.drawTop();
64+
final int p2 = player2.drawTop();
65+
if (player1.cardCountIsAtLeast(p1) && player2.cardCountIsAtLeast(p2)) {
66+
final var winner = playGame(player1.clone(p1), player2.clone(p2));
67+
if (winner.id == player1.id) {
68+
player1.addToBottom(p1);
69+
player1.addToBottom(p2);
70+
} else {
71+
player2.addToBottom(p2);
72+
player2.addToBottom(p1);
73+
}
74+
} else {
75+
if (p1 > p2) {
76+
player1.addToBottom(p1);
77+
player1.addToBottom(p2);
78+
} else {
79+
player2.addToBottom(p2);
80+
player2.addToBottom(p1);
81+
}
82+
}
83+
}
84+
return player1.hasCards() ? player1 : player2;
85+
}
86+
87+
protected static class Player {
88+
final int id;
89+
final List<Integer> deck;
90+
91+
public Player(final int id, final List<Integer> deck) {
92+
this.id = id;
93+
this.deck = deck;
94+
}
95+
96+
public boolean hasCards() {
97+
return !deck.isEmpty();
98+
}
99+
100+
public boolean cardCountIsAtLeast(final int count) {
101+
return deck.size() >= count;
102+
}
103+
104+
public int drawTop() {
105+
return deck.remove(0);
106+
}
107+
108+
public void addToBottom(final int card) {
109+
deck.add(card);
110+
}
111+
112+
public Player clone(final int cardCount) {
113+
return new Player(id, new LinkedList<>(deck.subList(0, cardCount)));
114+
}
115+
116+
public int score() {
117+
int retval = 0;
118+
int multiplier = deck.size();
119+
for (final var card : deck) {
120+
retval += card * (multiplier--);
121+
}
122+
return retval;
123+
}
124+
}
125+
126+
protected static class Round {
127+
private final List<Integer> x;
128+
private final List<Integer> y;
129+
130+
public Round(final List<Integer> x, final List<Integer> y) {
131+
this.x = List.copyOf(x);
132+
this.y = List.copyOf(y);
133+
}
134+
135+
public Round(final Player x, final Player y) {
136+
this(x.deck, y.deck);
137+
}
138+
139+
public int hashCode() {
140+
return Objects.hash(x, y);
141+
}
142+
143+
public boolean equals(final Object o) {
144+
if (this == o) {
145+
return true;
146+
} else if (o == null) {
147+
return false;
148+
}
149+
try {
150+
final Round other = (Round) o;
151+
return Objects.equals(x, other.x) && Objects.equals(y, other.y);
152+
} catch (final ClassCastException cce) {
153+
return false;
154+
}
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)