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)
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