Skip to content

Commit 7d50e41

Browse files
committed
day 17, part 2 unfinished
1 parent d6ed9ef commit 7d50e41

File tree

10 files changed

+344
-0
lines changed

10 files changed

+344
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.codefork.aoc2024.day17;
2+
3+
public final class Combo extends Operand {
4+
public Combo(int value) {
5+
super(value);
6+
}
7+
8+
@Override
9+
public int eval(Computer computer) {
10+
return switch (value) {
11+
case 0, 1, 2, 3 -> value;
12+
case 4 -> computer.a();
13+
case 5 -> computer.b();
14+
case 6 -> computer.c();
15+
default -> throw new RuntimeException("this should never happen");
16+
};
17+
}
18+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.codefork.aoc2024.day17;
2+
3+
import java.util.Arrays;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.regex.Pattern;
8+
import java.util.stream.Stream;
9+
10+
import static com.codefork.aoc2024.util.FoldLeft.foldLeft;
11+
12+
public record Computer(int a, int b, int c, int ip, List<Integer> program, String output) {
13+
14+
private static final Map<Integer, Instruction> opcodesToInstructions = Instruction.opcodesToInstructions();
15+
16+
private static final Pattern registerPat = Pattern.compile("Register ([ABC]): (\\d+)");
17+
private static final Pattern programPat = Pattern.compile("Program: ([\\d,]+)");
18+
19+
public static Computer parse(Stream<String> data) {
20+
return data.collect(foldLeft(
21+
() -> new Computer(0, 0, 0, 0, Collections.emptyList(), ""),
22+
(acc, line) -> {
23+
var lineMatcher = registerPat.matcher(line);
24+
var progMatcher = programPat.matcher(line);
25+
if(lineMatcher.find()) {
26+
var reg = lineMatcher.group(1);
27+
var value = Integer.parseInt(lineMatcher.group(2));
28+
return switch(reg) {
29+
case "A" -> acc.withA(value);
30+
case "B" -> acc.withB(value);
31+
case "C" -> acc.withC(value);
32+
default -> throw new RuntimeException("unrecognized register: " + reg);
33+
};
34+
} else if(progMatcher.find()) {
35+
var programStr = progMatcher.group(1);
36+
var program = Arrays.stream(programStr.split(",")).map(Integer::parseInt).toList();
37+
return acc.withProgram(program);
38+
} else {
39+
return acc;
40+
}
41+
})
42+
);
43+
}
44+
45+
public Computer withA(int newA) {
46+
return new Computer(newA, b, c, ip, program, output);
47+
}
48+
49+
public Computer withB(int newB) {
50+
return new Computer(a, newB, c, ip, program, output);
51+
}
52+
53+
public Computer withC(int newC) {
54+
return new Computer(a, b, newC, ip, program, output);
55+
}
56+
57+
public Computer withIp(int newIp) {
58+
return new Computer(a, b, c, newIp, program, output);
59+
}
60+
61+
public Computer withProgram(List<Integer> newProgram) {
62+
return new Computer(a, b, c, ip, newProgram, output);
63+
}
64+
65+
// advance by 2, for "normal" instructions
66+
public Computer advanceIp() {
67+
return new Computer(a, b, c, ip + 2, program, output);
68+
}
69+
70+
public Computer appendOutput(int item) {
71+
var newOutput = output + (!output.isEmpty() ? "," : "") + item;
72+
return new Computer(a, b, c, ip, program, newOutput);
73+
}
74+
75+
public Computer run() {
76+
var state = this;
77+
while(state.ip() <= state.program.size() - 2) {
78+
var opcode = state.program().get(state.ip());
79+
var rawOperand = state.program().get(state.ip()+1);
80+
var instruction = opcodesToInstructions.get(opcode);
81+
var operand = instruction.parseOperand(rawOperand);
82+
state = instruction.apply(operand, state);
83+
}
84+
return state;
85+
}
86+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package com.codefork.aoc2024.day17;
2+
3+
import java.util.Arrays;
4+
import java.util.Map;
5+
import java.util.stream.Collectors;
6+
7+
public enum Instruction {
8+
adv {
9+
@Override
10+
public int opcode() {
11+
return 0;
12+
}
13+
14+
@Override
15+
public Operand parseOperand(int operand) {
16+
return new Combo(operand);
17+
}
18+
19+
@Override
20+
public Computer apply(Operand operand, Computer computer) {
21+
var operandEvaluated = operand.eval(computer);
22+
var result = computer.a() / (int) Math.pow(2, operandEvaluated);
23+
return computer.withA(result).advanceIp();
24+
}
25+
},
26+
bxl {
27+
@Override
28+
public int opcode() {
29+
return 1;
30+
}
31+
32+
@Override
33+
public Operand parseOperand(int operand) {
34+
return new Literal(operand);
35+
}
36+
37+
@Override
38+
public Computer apply(Operand operand, Computer computer) {
39+
var operandEvaluated = operand.eval(computer);
40+
var result = computer.b() ^ operandEvaluated;
41+
return computer.withB(result).advanceIp();
42+
}
43+
},
44+
bst {
45+
@Override
46+
public int opcode() {
47+
return 2;
48+
}
49+
50+
@Override
51+
public Operand parseOperand(int operand) {
52+
return new Combo(operand);
53+
}
54+
55+
@Override
56+
public Computer apply(Operand operand, Computer computer) {
57+
var operandEvaluated = operand.eval(computer);
58+
var result = operandEvaluated % 8;
59+
return computer.withB(result).advanceIp();
60+
}
61+
},
62+
jnz {
63+
@Override
64+
public int opcode() {
65+
return 3;
66+
}
67+
68+
@Override
69+
public Operand parseOperand(int operand) {
70+
return new Literal(operand);
71+
}
72+
73+
@Override
74+
public Computer apply(Operand operand, Computer computer) {
75+
var operandEvaluated = operand.eval(computer);
76+
if(computer.a() != 0) {
77+
return computer.withIp(operandEvaluated);
78+
}
79+
return computer.advanceIp();
80+
}
81+
},
82+
bxc {
83+
@Override
84+
public int opcode() {
85+
return 4;
86+
}
87+
88+
@Override
89+
public Operand parseOperand(int operand) {
90+
return new Literal(operand);
91+
}
92+
93+
@Override
94+
public Computer apply(Operand operand, Computer computer) {
95+
var result = computer.b() ^ computer.c();
96+
return computer.withB(result).advanceIp();
97+
}
98+
},
99+
out {
100+
@Override
101+
public int opcode() {
102+
return 5;
103+
}
104+
105+
@Override
106+
public Operand parseOperand(int operand) {
107+
return new Combo(operand);
108+
}
109+
110+
@Override
111+
public Computer apply(Operand operand, Computer computer) {
112+
var operandEvaluated = operand.eval(computer);
113+
var result = operandEvaluated % 8;
114+
return computer.appendOutput(result).advanceIp();
115+
}
116+
},
117+
bdv {
118+
@Override
119+
public int opcode() {
120+
return 6;
121+
}
122+
123+
@Override
124+
public Operand parseOperand(int operand) {
125+
return new Combo(operand);
126+
}
127+
128+
@Override
129+
public Computer apply(Operand operand, Computer computer) {
130+
var operandEvaluated = operand.eval(computer);
131+
var result = computer.a() / (int) Math.pow(2, operandEvaluated);
132+
return computer.withB(result).advanceIp();
133+
}
134+
},
135+
cdv {
136+
@Override
137+
public int opcode() {
138+
return 7;
139+
}
140+
141+
@Override
142+
public Operand parseOperand(int operand) {
143+
return new Combo(operand);
144+
}
145+
146+
@Override
147+
public Computer apply(Operand operand, Computer computer) {
148+
var operandEvaluated = operand.eval(computer);
149+
var result = computer.a() / (int) Math.pow(2, operandEvaluated);
150+
return computer.withC(result).advanceIp();
151+
}
152+
};
153+
154+
public abstract int opcode();
155+
156+
public abstract Operand parseOperand(int operand);
157+
158+
public abstract Computer apply(Operand operand, Computer computer);
159+
160+
public static Map<Integer, Instruction> opcodesToInstructions() {
161+
return Arrays.stream(Instruction.values())
162+
.collect(Collectors.toMap(Instruction::opcode, (i) -> i));
163+
164+
}
165+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.codefork.aoc2024.day17;
2+
3+
public final class Literal extends Operand {
4+
public Literal(int value) {
5+
super(value);
6+
}
7+
8+
@Override
9+
public int eval(Computer computer) {
10+
return value;
11+
}
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.codefork.aoc2024.day17;
2+
3+
public abstract sealed class Operand permits Literal, Combo {
4+
protected final int value;
5+
6+
public Operand(int value) {
7+
this.value = value;
8+
}
9+
10+
public abstract int eval(Computer computer);
11+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.codefork.aoc2024.day17;
2+
3+
import com.codefork.aoc2024.Problem;
4+
import com.codefork.aoc2024.util.Assert;
5+
6+
import java.util.stream.Stream;
7+
8+
public class Part01 extends Problem {
9+
10+
public String solve(Stream<String> data) {
11+
var computer = Computer.parse(data);
12+
var finalState = computer.run();
13+
return finalState.output();
14+
}
15+
16+
@Override
17+
public String solve() {
18+
Assert.assertEquals("4,6,3,5,6,3,5,2,1,0", solve(getSampleInput()));
19+
return solve(getInput());
20+
}
21+
22+
public static void main(String[] args) {
23+
new Part01().run();
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.codefork.aoc2024.day17;
2+
3+
import com.codefork.aoc2024.Problem;
4+
import com.codefork.aoc2024.util.Assert;
5+
6+
import java.util.stream.Stream;
7+
8+
public class Part02 extends Problem {
9+
10+
public String solve(Stream<String> data) {
11+
// var computer = Computer.parse(data);
12+
// var finalState = computer.run();
13+
// return finalState.output();
14+
return "";
15+
}
16+
17+
@Override
18+
public String solve() {
19+
//Assert.assertEquals("0,3,5,4,3,0", solve(getFileAsStream("sample2")));
20+
//return solve(getInput());
21+
return "UNFINISHED";
22+
}
23+
24+
public static void main(String[] args) {
25+
new Part02().run();
26+
}
27+
}

src/main/resources/day17/input

113 Bytes
Binary file not shown.

src/main/resources/day17/sample

88 Bytes
Binary file not shown.

src/main/resources/day17/sample2

89 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)