2024-12-17 01:13:47 -05:00
|
|
|
#!/usr/bin/env ruby
|
|
|
|
|
|
|
|
require "debug"
|
2024-12-17 12:05:03 -05:00
|
|
|
DEBUG = false
|
2024-12-17 01:13:47 -05:00
|
|
|
|
|
|
|
input = (ARGV.first.nil? ? DATA : ARGF)
|
|
|
|
.readlines(chomp: true)
|
|
|
|
split = input.index("")
|
|
|
|
|
|
|
|
registers = input[...split]
|
|
|
|
.map { _1.split(": ") }
|
|
|
|
.map(&:last)
|
|
|
|
.map(&:to_i)
|
|
|
|
.zip(%i[A B C])
|
|
|
|
.map(&:reverse)
|
|
|
|
.to_h
|
|
|
|
program = input[split+1]
|
|
|
|
.split(" ")
|
|
|
|
.last
|
|
|
|
.split(",")
|
|
|
|
.map(&:to_i)
|
|
|
|
|
|
|
|
OPERANDS = [
|
|
|
|
->() { 0 }, ->() { 1 }, ->() { 2 }, ->() { 3 },
|
|
|
|
->() { registers[:A] },
|
|
|
|
->() { registers[:B] },
|
|
|
|
->() { registers[:C] },
|
|
|
|
->() { :noop },
|
|
|
|
]
|
|
|
|
|
2024-12-17 01:25:41 -05:00
|
|
|
def execute(registers, program)
|
2024-12-17 08:52:46 -05:00
|
|
|
stdout, commands = Array.new, Array.new
|
2024-12-17 01:13:47 -05:00
|
|
|
|
2024-12-17 12:05:03 -05:00
|
|
|
ic = 0
|
|
|
|
while ic < program.size
|
|
|
|
opcode = program[ic]
|
|
|
|
literal_operand = program[ic+1]
|
2024-12-17 01:25:41 -05:00
|
|
|
combo_operand = OPERANDS[literal_operand].call
|
2024-12-17 01:13:47 -05:00
|
|
|
|
2024-12-17 12:05:03 -05:00
|
|
|
ic += 2
|
2024-12-17 01:13:47 -05:00
|
|
|
|
2024-12-17 01:25:41 -05:00
|
|
|
case opcode
|
|
|
|
when 0
|
|
|
|
numerator = registers[:A]
|
|
|
|
denominator = 2 ** combo_operand
|
|
|
|
registers[:A] = numerator / denominator
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:adv, numerator, denominator]
|
2024-12-17 01:25:41 -05:00
|
|
|
when 1
|
|
|
|
registers[:B] = registers[:B] ^ literal_operand
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:bxl, literal_operand]
|
2024-12-17 01:25:41 -05:00
|
|
|
when 2
|
|
|
|
registers[:B] = combo_operand % 8
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:bst, combo_operand % 8]
|
2024-12-17 01:25:41 -05:00
|
|
|
when 3
|
|
|
|
if registers[:A] == 0
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:noop]
|
2024-12-17 01:25:41 -05:00
|
|
|
else
|
2024-12-17 12:05:03 -05:00
|
|
|
ic = literal_operand
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:jnz, literal_operand]
|
2024-12-17 01:25:41 -05:00
|
|
|
end
|
|
|
|
when 4
|
|
|
|
registers[:B] = registers[:B] ^ registers[:C]
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:bxc, registers[:B], registers[:C]]
|
2024-12-17 01:25:41 -05:00
|
|
|
when 5
|
|
|
|
stdout << combo_operand % 8
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:out, combo_operand % 8]
|
2024-12-17 01:25:41 -05:00
|
|
|
when 6
|
|
|
|
numerator = registers[:A]
|
|
|
|
denominator = 2 ** combo_operand
|
|
|
|
registers[:B] = numerator / denominator
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:bdv, numerator, denominator]
|
2024-12-17 01:25:41 -05:00
|
|
|
when 7
|
|
|
|
numerator = registers[:A]
|
|
|
|
denominator = 2 ** combo_operand
|
|
|
|
registers[:C] = numerator / denominator
|
2024-12-17 08:52:46 -05:00
|
|
|
commands << [:cdv, numerator, denominator]
|
2024-12-17 01:13:47 -05:00
|
|
|
end
|
|
|
|
end
|
2024-12-17 01:25:41 -05:00
|
|
|
|
2024-12-17 12:05:03 -05:00
|
|
|
if DEBUG
|
|
|
|
commands.each { puts _1.join(" ") }
|
|
|
|
end
|
2024-12-17 08:52:46 -05:00
|
|
|
|
2024-12-17 01:25:41 -05:00
|
|
|
[registers, program, stdout.join(",")]
|
2024-12-17 01:13:47 -05:00
|
|
|
end
|
|
|
|
|
2024-12-17 12:05:03 -05:00
|
|
|
part_2 = registers[:A].dup
|
2024-12-17 01:25:41 -05:00
|
|
|
_, _, part_1 = execute(registers, program)
|
|
|
|
p part_1
|
2024-12-17 01:13:47 -05:00
|
|
|
|
2024-12-17 12:05:03 -05:00
|
|
|
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$/)
|
|
|
|
end
|
|
|
|
|
|
|
|
while part_2 <<= 3
|
|
|
|
registers = {A: part_2, B: 0, C: 0}
|
|
|
|
_, _, output = execute(registers, program)
|
|
|
|
|
|
|
|
next if output.size < 31
|
|
|
|
p "#{part_2} (b): #{output}"
|
|
|
|
raise if output.size > 31
|
|
|
|
end
|
2024-12-17 01:13:47 -05:00
|
|
|
|
|
|
|
__END__
|
2024-12-17 01:25:41 -05:00
|
|
|
Register A: 2024
|
2024-12-17 01:13:47 -05:00
|
|
|
Register B: 0
|
|
|
|
Register C: 0
|
|
|
|
|
2024-12-17 01:25:41 -05:00
|
|
|
Program: 0,3,5,4,3,0
|