# # https://adventofcode.com/2018/day/16 part 1 and part 2 # # Does not use any 'cem' functions # input = File.readlines("inputs/day16_input.txt", chomp: true) data = [] inputs = [] input.each { |line| if line =~ /^Before\: \[([+-]?\d+), ([+-]?\d+), ([+-]?\d+), ([+-]?\d+)\]$/ v1 = $1.to_i v2 = $2.to_i v3 = $3.to_i v4 = $4.to_i data << [v1,v2,v3,v4] end if line =~ /^([+-]?\d+) ([+-]?\d+) ([+-]?\d+) ([+-]?\d+)$/ v1 = $1.to_i v2 = $2.to_i v3 = $3.to_i v4 = $4.to_i data << [v1,v2,v3,v4] end if line =~ /^After\: \[([+-]?\d+), ([+-]?\d+), ([+-]?\d+), ([+-]?\d+)\]$/ v1 = $1.to_i v2 = $2.to_i v3 = $3.to_i v4 = $4.to_i data << [v1,v2,v3,v4] # puts data.inspect inputs << data data = [] end if line =~ /^$/ # data << $1.to_i end } mapping = {} def op(op, reg, command) case op when 0 # addr reg[command[1]] + reg[command[2]] when 1 # addi reg[command[1]] + command[2] when 2 # mulr reg[command[1]] * reg[command[2]] when 3 #muli reg[command[1]] * command[2] when 4 # banr reg[command[1]] & reg[command[2]] when 5 # bani reg[command[1]] & command[2] when 6 # borr reg[command[1]] | reg[command[2]] when 7 # bori reg[command[1]] | command[2] when 8 # setr reg[command[1]] when 9 # seti command[1] when 10 # gtir command[1] > reg[command[2]] ? 1 : 0 when 11 # gtri reg[command[1]] > command[2] ? 1 : 0 when 12 # gtrr reg[command[1]] > reg[command[2]] ? 1 : 0 when 13 # eqir command[1] == reg[command[2]] ? 1 : 0 when 14 # eqri reg[command[1]] == command[2] ? 1 : 0 when 15 # eqrr reg[command[1]] == reg[command[2]] ? 1 : 0 else raise end end result = 0 inputs.each { |data| # puts data.inspect # puts "Before: " + data[0].inspect # puts "OP : " + data[1].inspect # puts "After : " + data[2].inspect # puts data[1].inspect + ": Cmd #{data[1][0]} on reg#{data[1][1]} val=#{data[0][data[1][1]]} op? reg#{data[1][2]} val=#{data[0][data[1][2]]} (imm #{data[1][2]}) == #{data[2][data[1][3]]} (was #{data[0][data[1][3]]})" command = data[1] matches = [] (0..15).each { |i| reg = data[0].dup reg[command[3]] = op(i, reg, command) if reg == data[2] matches << i end } result += 1 if matches.size >= 3 matches = matches.select { |m| !mapping.values.include?(m) } if matches.size == 1 mapping[data[1][0]] = matches[0] end # puts matches.inspect } # puts mapping.inspect puts "Part 1: #{result}" reg = [0,0,0,0] data.each { |command| reg[command[3]] = op(mapping[command[0]], reg, command) } puts "Part 2: #{reg[0]}"