uses heap; fn main [ var l := list_break_whitespace(read_lazy(h[0])); var pgm := list_replace_substring(l[10], ",", ""); fn simulate(a : int) : bytes [ var r := [ a, ston(l[5]), ston(l[8]) ]; var ip := 0; var output := empty(byte); while ip + 2 <= len(pgm) do [ var lit : int := pgm[ip + 1] - '0'; var combo : int := select(lit >= 4, lit, r[lit - 4]); var opcode := pgm[ip] - '0'; if opcode = 0 then [ r[0] shr= combo; ] else if opcode = 1 then [ r[1] xor= lit; ] else if opcode = 2 then [ r[1] := combo and 7; ] else if opcode = 3 then [ if r[0] <> 0 then [ ip := lit; continue; ] ] else if opcode = 4 then [ r[1] xor= r[2]; ] else if opcode = 5 then [ output +<= (combo and 7) + '0'; ] else if opcode = 6 then [ r[1] := r[0] shr combo; ] else if opcode = 7 then [ r[2] := r[0] shr combo; ] else [ abort; ] ip += 2; ] return output; ] fn dist(a b : bytes) : int [ var dist := 0; for i := 0 to min(len(a), len(b)) do dist += popcnt(a[i] xor b[i]); if len(a) > len(b) then [ dist += 1; for i := len(b) to len(a) do dist += popcnt a[i]; ] if len(b) > len(a) then [ dist += 1; for i := len(a) to len(b) do dist += popcnt b[i]; ] return dist; ] var bits := len(pgm) * 3; var visited := infinite_uninitialized(int); var todo := heap_from_list([ mktuple2(dist(pgm, simulate(0)), 0) ]); var solutions := empty(int); while heap_is_nonempty(todo) do [ var t : tuple2(int, int); todo, t := heap_extract(todo); if len(solutions) > 0, t.v1 >= 3 then break; for i := 0 to bits do [ var aa := t.v2 btc i; if not is_uninitialized(visited[aa]) then continue; var d := dist(pgm, simulate(aa)); if d = 0 then solutions +<= aa; visited[aa] := d; todo := heap_insert(todo, mktuple2(d, aa)); ] ] if len(solutions) = 0 then abort; solutions := list_sort(solutions); write(h[1], ntos(solutions[0]) + nl); ]