-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathDay22.java
88 lines (75 loc) · 2.32 KB
/
Day22.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package com.sbaars.adventofcode.year20.days;
import com.sbaars.adventofcode.year20.Day2020;
import java.util.*;
import java.util.stream.LongStream;
import static java.lang.Math.toIntExact;
import static java.util.stream.Collectors.toCollection;
public class Day22 extends Day2020 {
public Day22() {
super(22);
}
public static void main(String[] args) {
new Day22().printParts();
}
@Override
public Object part1() {
String[] input = day().split("\n\n");
Deque<Long> p1 = getInput(0, input);
Deque<Long> p2 = getInput(1, input);
while (p1.size() > 0 && p2.size() > 0) {
long l1 = p1.pop();
long l2 = p2.pop();
if (l1 > l2) {
p1.add(l1);
p1.add(l2);
} else {
p2.add(l2);
p2.add(l1);
}
}
Deque<Long> winner = p1.size() > 0 ? p1 : p2;
return calcScore(winner);
}
private long calcScore(Deque<Long> winner) {
return LongStream.rangeClosed(1, winner.size()).boxed().sorted(Comparator.reverseOrder()).mapToLong(l -> winner.pop() * l).sum();
}
@Override
public Object part2() {
String[] input = day().split("\n\n");
Deque<Long> p1 = getInput(0, input);
Deque<Long> p2 = getInput(1, input);
return calcScore(playGame(p1, p2) == Player.P1 ? p1 : p2);
}
private ArrayDeque<Long> getInput(int i, String[] input) {
return Arrays.stream(input[i].split("\n")).filter(e -> !e.startsWith("Player")).map(Long::parseLong).collect(toCollection(ArrayDeque::new));
}
public Player playGame(Deque<Long> p1, Deque<Long> p2) {
Set<List<Long>> playedGames = new HashSet<>();
while (p1.size() > 0 && p2.size() > 0) {
if (!playedGames.add(new ArrayList<>(p1))) {
return Player.P1;
}
long l1 = p1.pop();
long l2 = p2.pop();
if (p1.size() < l1 || p2.size() < l2) {
if (l1 > l2) {
p1.add(l1);
p1.add(l2);
} else {
p2.add(l2);
p2.add(l1);
}
} else {
if (playGame(new ArrayDeque<>(new ArrayList<>(p1).subList(0, toIntExact(l1))), new ArrayDeque<>(new ArrayList<>(p2).subList(0, toIntExact(l2)))) == Player.P1) {
p1.add(l1);
p1.add(l2);
} else {
p2.add(l2);
p2.add(l1);
}
}
}
return p1.size() > 0 ? Player.P1 : Player.P2;
}
enum Player {P1, P2}
}