Ah, the madness continues... This is for day 2 of Advent of Code 2019.
What follows is an example input and how it changes with each step. The arrow is the current execution pointer.
||1|2|3|4|5|6|7|8|9|10|11| ||:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:| |1|9|10|3|2|3|11||99|30|40|50| |1|9|10|70|2|3|11||99|30|40|50| |3500|9|10|70|2|3|11||99|30|40|50|
First, let’s read data from the file and convert into a list of numbers. We use the same code as before, dumping the commas by simply picking the elements in the odd positions. This is our “original” program.
w =. ;: 1!:1 <'original' o =: ". > ((#w) $ 1 0) # w
Then we need a function that takes the program, and an instruction pointer, executes it, modifies the program, and calls itself again, until we’re done.
This is not J-style array processing, sadly!
step =: dyad define select. y { x case. 1 do. a =. ((y+1){x){x b =. ((y+2){x){x c =. ((y+3){x) n =. (a + b) c } x n step y+4 case. 2 do. a =. ((y+1){x){x b =. ((y+2){x){x c =. ((y+3){x) n =. (a * b) c } x n step y+4 case. 99 do. 0 { x end. )
Some notes:
select.
case.
do.
end.
is similar to other languages3 { x
gets the third element from list x
{
gives us the address we need to look at, and the second {
gives us the value at that address4 5 } x
gives us a copy of x
where the fifth value has been replaced by the number 4, which is why we need pass this modified value along to the next callThis computes the solution for part 1 of the challenge:
o step 0
What’s trickier to do is the second part. We are asked to “fix” the program by replacing the second and first number by all the numbers between 0 and 99 inclusive and find the pair that results in some magic value...
Here’s how to “fix” the program:
fix =. 1 2 }
And this is how you use it. The list to the left has to be exactly two elements long.
6 7 fix 1 2 3 4 5 1 6 7 4 5
Next we need a function that takes the original program, fixes is based on the two arguments, and computes the result using our step
function.
try =. (4 : '((x, y) fix o) step 0')"0
Notable things that gave me headaches:
(x, y)
which is different from (6 7)
because space-separated numbers are a thing of their own, where as space-separated identifiers are an application.Here’s one example of how to call it:
12 try 2
And now let’s create a 100×100 matrix and call try for every single pair:
try/~i.100
To pick this apart:
i.100
creates a list of 0–99~
is an “adverb” and modifies the preceding “verb” such that it gets called with two copies of it’s argument, so two lists of 0–99 instead of one .../
is an “adverb” and modifies the preceding “verb” such that it results in a table, getting called for every a in x and every b in y ...try
is our “verb” – so in effect we’re calling 0 try 0
, 0 try 1
, ... which is just what we wantedBut actually we only care for the one call that produced the correct result:
19690720=try/~i.100
This gives us a truth table: a table full of zeroes and a single one. All we need to do is unravel the matrix and find the index of that single true value and we’re done.
The reason that we’re done is that the solution is “What is 100 _ noun + verb?” Not quite surprisingly, as 100 is the length of a row, that’s exactly what we’re getting._
I.,19690720=try/~i.100
,
unravels the matrixI.
find the index and defaults to finding the value 1#J #Programming #Advent of Code
text/gemini
This content has been proxied by September (ba2dc).