-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathDay9.java
92 lines (77 loc) · 2.07 KB
/
Day9.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
89
90
91
92
package com.sbaars.adventofcode.year18.days;
import com.sbaars.adventofcode.common.map.LongCountMap;
import com.sbaars.adventofcode.year18.Day2018;
import static com.sbaars.adventofcode.util.DataMapper.readString;
import static java.lang.Math.toIntExact;
public class Day9 extends Day2018 {
public Day9() {
super(9);
}
public static void main(String[] args) {
new Day9().printParts();
}
public record Input(long nPlayers, long lastMarble) {
}
private static class Node {
final long value;
Node prev;
Node next;
Node(long value) {
this.value = value;
this.prev = this;
this.next = this;
}
void insert(Node node) {
node.next = this.next;
node.prev = this;
this.next.prev = node;
this.next = node;
}
Node remove() {
this.prev.next = this.next;
this.next.prev = this.prev;
return this.next;
}
Node move(int steps) {
Node current = this;
if (steps > 0) {
for (int i = 0; i < steps; i++) {
current = current.next;
}
} else {
for (int i = 0; i < -steps; i++) {
current = current.prev;
}
}
return current;
}
}
@Override
public Object part1() {
return calcOutput(false);
}
private long calcOutput(boolean part2) {
Input input = readString(day().trim(), "%n players; last marble is worth %n points", Input.class);
int nMarbles = toIntExact(input.lastMarble) * (part2 ? 100 : 1);
Node current = new Node(0);
LongCountMap<Long> scores = new LongCountMap<>();
for (int i = 1; i <= nMarbles; i++) {
if (i % 23 == 0) {
long player = (i - 1) % input.nPlayers;
scores.increment(player, i);
current = current.move(-7);
scores.increment(player, current.value);
current = current.remove();
} else {
Node newNode = new Node(i);
current.move(1).insert(newNode);
current = newNode;
}
}
return scores.max();
}
@Override
public Object part2() {
return calcOutput(true);
}
}