Skip to content

Commit d60432c

Browse files
committed
use the the actual Run method for part2 making it input agnostic
1 parent 9fd6a0d commit d60432c

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

2024/Day17/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ There is _some interconnection_ between the consecutive numbers, so one cannot j
2121
for each. But I was able to come up with a _recursive solution_ that generates the input _backwards_. Once we know the
2222
higher bits, we can try all combinations for the next 3 bits, and so on down to the first bit.
2323

24-
As an added bonus I implemented (part of) the emulator in [VIC-20 BASIC](https://hu.wikipedia.org/wiki/Commodore_VIC-20). This is how it runs the second sample that prints out its own source code.
24+
As an added bonus I implemented (part of) the emulator in [VIC-20 BASIC](https://hu.wikipedia.org/wiki/Commodore_VIC-20).
25+
This is how it runs the second sample that prints out its own source code.
2526

2627
![vic20.gif](vic20.gif)

2024/Day17/Solution.cs

+26-27
Original file line numberDiff line numberDiff line change
@@ -11,61 +11,60 @@ enum Opcode {
1111
Adv, Bxl, Bst, Jnz, Bxc, Out, Bdv, Cdv
1212
}
1313

14-
public object PartOne(string input) => Run(input);
15-
public object PartTwo(string input) => GenerateA(Parse(input).program.ToList()).Min();
16-
17-
string Run(string input) {
14+
public object PartOne(string input) {
1815
var (state, program) = Parse(input);
19-
var combo = (long op) => op < 4 ? (int)op : (int)state[op - 4];
20-
var res = new List<int>();
21-
for (var ip = 0; ip < program.Length; ip += 2) {
22-
switch ((Opcode)program[ip], program[ip + 1]) {
23-
case (Opcode.Adv, var op): state[0] = state[0] >> combo(op); break;
24-
case (Opcode.Bdv, var op): state[1] = state[0] >> combo(op); break;
25-
case (Opcode.Cdv, var op): state[2] = state[0] >> combo(op); break;
16+
return string.Join(",", Run(state, program));
17+
}
18+
public object PartTwo(string input) {
19+
var (_, program) = Parse(input);
20+
return GenerateA(program, program).Min();
21+
}
22+
23+
List<long> Run(List<long> state, List<long> program) {
24+
var combo = (int op) => op < 4 ? op : state[op - 4];
25+
var res = new List<long>();
26+
for (var ip = 0; ip < program.Count; ip += 2) {
27+
switch ((Opcode)program[ip], (int)program[ip + 1]) {
28+
case (Opcode.Adv, var op): state[0] = state[0] >> (int)combo(op); break;
29+
case (Opcode.Bdv, var op): state[1] = state[0] >> (int)combo(op); break;
30+
case (Opcode.Cdv, var op): state[2] = state[0] >> (int)combo(op); break;
2631
case (Opcode.Bxl, var op): state[1] = state[1] ^ op; break;
2732
case (Opcode.Bst, var op): state[1] = combo(op) % 8; break;
28-
case (Opcode.Jnz, var op): ip = state[0] == 0 ? ip : (int)op - 2; break;
33+
case (Opcode.Jnz, var op): ip = state[0] == 0 ? ip : op - 2; break;
2934
case (Opcode.Bxc, var op): state[1] = state[1] ^ state[2]; break;
3035
case (Opcode.Out, var op): res.Add(combo(op) % 8); break;
3136
}
3237
}
33-
return string.Join(",", res);
38+
return res;
3439
}
3540

3641
/*
37-
Determines register A for the given output. The search works recursively and in reverse order,
38-
starting from the last number to be printed and ending with the first.
42+
Determines register A for the given output. The search works recursively and in
43+
reverse order, starting from the last number to be printed and ending with the first.
3944
*/
40-
IEnumerable<long> GenerateA(List<long> output) {
45+
IEnumerable<long> GenerateA(List<long> program, List<long> output) {
4146
if (!output.Any()) {
4247
yield return 0;
4348
yield break;
4449
}
4550

46-
// this loop is pretty much the assembly code of the program reimplemented in c#
47-
foreach (var ah in GenerateA(output[1..])) {
51+
foreach (var ah in GenerateA(program, output[1..])) {
4852
for (var al = 0; al < 8; al++) {
4953
var a = ah * 8 + al;
50-
long b = a % 8;
51-
b = b ^ 3;
52-
var c = a >> (int)b;
53-
b = b ^ c;
54-
b = b ^ 5;
55-
if (output[0] == b % 8) {
54+
if (Run([a, 0, 0], program).SequenceEqual(output)) {
5655
yield return a;
5756
}
5857
}
5958
}
6059
}
6160

62-
(long[] state, long[] program) Parse(string input) {
61+
(List<long> state, List<long> program) Parse(string input) {
6362
var blocks = input.Split("\n\n").Select(ParseNums).ToArray();
6463
return (blocks[0], blocks[1]);
6564
}
6665

67-
long[] ParseNums(string st) =>
66+
List<long> ParseNums(string st) =>
6867
Regex.Matches(st, @"\d+", RegexOptions.Multiline)
6968
.Select(m => long.Parse(m.Value))
70-
.ToArray();
69+
.ToList();
7170
}

0 commit comments

Comments
 (0)