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