I'm new to code golf challenges. My problem came up in Advent of Code 2020 Day 8
The input is an array of arrays. In part two of the problem one needs to run several trials to produce a result by changing an element in the input array. My current code is this (comments added to explain what's going on):
p input.each_with_index { |val, i|
next if val[0] != :acc # not all elements need to be experimented with
changed = input.dup # clone input to make a change
# change the first element of the value at input position i (but keep the rest)
changed[i] = val.dup.tap { |v| v[0] = v[0] == :nop ? :jmp : :nop }
result = try_with(changed) # run the experiment
break result if result[1] == :terminate # success condition
end
So, that's quite a lot of code for something relatively simple. Can I make it shorter? Can I have a simple generator that produces different versions of the same array?
My complete code for day 8 is here
Edit:
As suggested in the comments, I'll try to put the problem my snippet is solving as a code golf challenge (note that this is just my snippet):
In ruby you have input
: an array of instructions. Each element of input
is another array of two elements, where the first is a symbol (the instruction name) which is one three: :acc
, :jmp
, or :nop
, and the second is an integer (the instruction argument).
You also have a function try_with
which works with such an array, executes the instructions and returns [n, :terminate]
if the program terminates or [n, :loop]
if the program is an endless loop. n
is the value of the accumulator after the execution.
The original input is a loop. If you change one of the instructions in the input array from :nop
to :jmp
or from :jmp
to :nop
, and keep the argument, it will result in a terminating program. What is the value of the accumulator after you find and execute the terminating program?
The original AOC2008D8 problem
You have a file with valid assembly. Each line is a three character instruction and a (possibly negative) integer argument separated by a single space. Example
nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6
Instructions are acc
add arg to accumulator and increment ip, jmp
add arg to ip, nop
ignore arg and just increment ip.
Then... what I said above about the snippet-only problem
Changing the next-to-last line in the example from jmp
to nop
results in a termination with acc value: 8