diff --git a/17/main.rb b/17/main.rb index 2068955..07fd227 100755 --- a/17/main.rb +++ b/17/main.rb @@ -20,22 +20,21 @@ program = input[split+1] .split(",") .map(&:to_i) -OPERANDS = [ - ->() { 0 }, ->() { 1 }, ->() { 2 }, ->() { 3 }, - ->() { registers[:A] }, - ->() { registers[:B] }, - ->() { registers[:C] }, - ->() { :noop }, -] - def execute(registers, program) stdout, commands = Array.new, Array.new + operands = [ + ->() { 0 }, ->() { 1 }, ->() { 2 }, ->() { 3 }, + ->() { registers[:A] }, + ->() { registers[:B] }, + ->() { registers[:C] }, + ->() { :noop }, + ] ic = 0 while ic < program.size opcode = program[ic] literal_operand = program[ic+1] - combo_operand = OPERANDS[literal_operand].call + combo_operand = operands[literal_operand].call ic += 2 @@ -84,25 +83,37 @@ def execute(registers, program) [registers, program, stdout.join(",")] end -part_2 = registers[:A].dup -_, _, part_1 = execute(registers, program) +_, _, part_1 = execute(registers.dup, program) p part_1 -while true - part_2 += 100_00 - registers = {A: part_2, B: 0, C: 0} - _, _, output = execute(registers, program) - p "#{part_2} (a): #{output}" - break if output.match?(/4,1,5,5,0,3,3,0$/) + +def reverse_engineer(program, slot, i) + candidates = (0..8).map do |i| + [i, execute({A: i, B: 0, C: 0}, program).last.split(",").map(&:to_i) + ] + end.select { _1.last == program[slot..] } end -while part_2 <<= 3 - registers = {A: part_2, B: 0, C: 0} - _, _, output = execute(registers, program) +part_2 = 0 +(program.size - 1).downto(0) do |slot| + candidates = [] + (0..8).each do |i| + candidate = part_2 + i + _, _, output = execute({A: candidate, B: 0, C: 0}, program) + new_program = output.split(",").map(&:to_i) - next if output.size < 31 - p "#{part_2} (b): #{output}" - raise if output.size > 31 + if new_program == program[slot..] + candidates << candidate + unless [301,2566855701950, 20534845615581, 20534845615573, 20534845615583].include?(candidate) + part_2 = candidate + end + end + end + #p candidates + if slot == 0 + p candidates.first + end + part_2 <<= 3 end __END__