#!/usr/bin/env ruby require "debug" 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 }, ] stdout = [] i = 0 while i < program.size opcode = program[i] literal_operand = program[i+1] combo_operand = OPERANDS[literal_operand].call i += 2 case opcode when 0 numerator = registers[:A] denominator = 2 ** combo_operand registers[:A] = numerator / denominator when 1 registers[:B] = registers[:B] ^ literal_operand when 2 registers[:B] = combo_operand % 8 when 3 if registers[:A] == 0 :noop else i = literal_operand end when 4 registers[:B] = registers[:B] ^ registers[:C] when 5 stdout << combo_operand % 8 when 6 numerator = registers[:A] denominator = 2 ** combo_operand registers[:B] = numerator / denominator when 7 numerator = registers[:A] denominator = 2 ** combo_operand registers[:C] = numerator / denominator end end p registers puts stdout.join(",") __END__ Register A: 729 Register B: 0 Register C: 0 Program: 0,1,5,4,3,0