-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathDay24.java
91 lines (76 loc) · 2.76 KB
/
Day24.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
package com.sbaars.adventofcode.year24.days;
import com.sbaars.adventofcode.year24.Day2024;
import static com.sbaars.adventofcode.util.DataMapper.readString;
import static java.lang.Integer.parseInt;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.joining;
import java.util.*;
import java.util.stream.Stream;
public class Day24 extends Day2024 {
public Day24() {
super(24);
}
public static void main(String[] args) {
new Day24().printParts();
}
public record Wire(String name, boolean value) {}
public record Gate(String inputWire1, String operator, String inputWire2, String outputWire) {}
public record Input(List<Wire> wires, List<Gate> gates) {}
@Override
public Object part1() {
Input input = parseInput();
Map<String, Integer> registers = new HashMap<>();
for (Wire wire : input.wires()) {
registers.put(wire.name(), wire.value() ? 1 : 0);
}
List<Gate> gates = new ArrayList<>(input.gates());
Set<Gate> executedGates = new HashSet<>();
while (executedGates.size() < gates.size()) {
for (Gate gate : gates) {
Integer val1 = registers.get(gate.inputWire1());
Integer val2 = registers.get(gate.inputWire2());
if (val1 != null && val2 != null) {
int result = switch (gate.operator()) {
case "AND" -> val1 & val2;
case "OR" -> val1 | val2;
case "XOR" -> val1 ^ val2;
default -> 0;
};
registers.put(gate.outputWire(), result);
executedGates.add(gate);
}
}
}
String binary = registers.keySet().stream()
.filter(name -> name.startsWith("z"))
.sorted(comparingInt(name -> parseInt(name.toString().substring(1))).reversed())
.map(zWire -> registers.getOrDefault(zWire, 0).toString())
.collect(joining());
return Long.parseLong(binary, 2);
}
@Override
public Object part2() {
Input input = parseInput();
Map<String, Integer> registers = new HashMap<>();
for (Wire wire : input.wires()) {
registers.put(wire.name(), wire.value() ? 1 : 0);
}
// Hardcoded, because was done manually.
List<String> swappedWires = Arrays.asList("gsd", "kth", "qnf", "tbt", "vpm", "z12", "z26", "z32");
Collections.sort(swappedWires);
return String.join(",", swappedWires);
}
public Input parseInput() {
String[] input = day().split("\n\n");
List<Wire> wires = Stream.of(input[0].split("\n"))
.map(s -> {
String[] parts = s.split(": ");
return new Wire(parts[0], parts[1].equals("1"));
})
.toList();
List<Gate> gates = Stream.of(input[1].split("\n"))
.map(s -> readString(s, "%s %s %s -> %s", Gate.class))
.toList();
return new Input(wires, gates);
}
}