aboutsummaryrefslogtreecommitdiff
path: root/day16/whodawhatnow
diff options
context:
space:
mode:
Diffstat (limited to 'day16/whodawhatnow')
-rwxr-xr-xday16/whodawhatnow141
1 files changed, 141 insertions, 0 deletions
diff --git a/day16/whodawhatnow b/day16/whodawhatnow
new file mode 100755
index 0000000..337cec1
--- /dev/null
+++ b/day16/whodawhatnow
@@ -0,0 +1,141 @@
+#!/usr/bin/env ruby
+
+input = $stdin.readlines.map(&:strip).reject(&:empty?)
+
+class Machine
+ def initialize(rs)
+ @rs = rs
+ end
+
+ def addr(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] + @rs[b]
+ nrs
+ end
+ def addi(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] + b
+ nrs
+ end
+ def mulr(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] * @rs[b]
+ nrs
+ end
+ def muli(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] * b
+ nrs
+ end
+ def banr(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] & @rs[b]
+ nrs
+ end
+ def bani(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] & b
+ nrs
+ end
+ def borr(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] | @rs[b]
+ nrs
+ end
+ def bori(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] | b
+ nrs
+ end
+ def setr(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a]
+ nrs
+ end
+ def seti(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = a
+ nrs
+ end
+ def gtir(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = a > @rs[b] ? 1 : 0
+ nrs
+ end
+ def gtri(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] > b ? 1 : 0
+ nrs
+ end
+ def gtrr(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] > @rs[b] ? 1 : 0
+ nrs
+ end
+ def eqir(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = a == @rs[b] ? 1 : 0
+ nrs
+ end
+ def eqri(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] == @rs[b] ? 1 : 0
+ nrs
+ end
+ def eqrr(a, b, c)
+ nrs = @rs.dup
+ nrs[c] = @rs[a] == @rs[b] ? 1 : 0
+ nrs
+ end
+
+ def oprs(a, b, c)
+ [
+ addr(a, b, c), addi(a, b, c),
+ mulr(a, b, c), muli(a, b, c),
+ banr(a, b, c), bani(a, b, c),
+ borr(a, b, c), bori(a, b, c),
+ setr(a, b, c), seti(a, b, c),
+ gtir(a, b, c), gtri(a, b, c), gtrr(a, b, c),
+ eqir(a, b, c), eqri(a, b, c), eqrr(a, b, c)
+ ]
+ end
+end
+
+oprsorder = {
+ 1<<15 => "addr", 1<<14 => "addi",
+ 1<<13 => "mulr", 1<<12 => "muli",
+ 1<<11 => "banr", 1<<10 => "bani",
+ 1<<9 => "borr", 1<<8 => "bori",
+ 1<<7 => "setr", 1<<6 => "seti",
+ 1<<5 => "gtir", 1<<4 => "grri", 1<<3 => "gtrr",
+ 1<<2 => "eqir", 1<<1 => "eqri", 1<<0 => "eqrr"
+}
+
+ops = [
+ 0b1111111111111111, 0b1111111111111111,
+ 0b1111111111111111, 0b1111111111111111,
+ 0b1111111111111111, 0b1111111111111111,
+ 0b1111111111111111, 0b1111111111111111,
+ 0b1111111111111111, 0b1111111111111111,
+ 0b1111111111111111, 0b1111111111111111, 0b1111111111111111,
+ 0b1111111111111111, 0b1111111111111111, 0b1111111111111111
+]
+
+input.each_slice(3) do |sample|
+ sample[0] =~ /Before: \[(\d+), (\d+), (\d+), (\d+)\]/
+ break if $1.nil?
+ m = Machine.new([$1.to_i, $2.to_i, $3.to_i, $4.to_i])
+
+ sample[1] =~ /(\d+) (\d+) (\d+) (\d+)/
+ opc = $1.to_i
+ oprs = m.oprs($2.to_i, $3.to_i, $4.to_i)
+
+ sample[2] =~ /After: \[(\d+), (\d+), (\d+), (\d+)\]/
+ a = [$1.to_i, $2.to_i, $3.to_i, $4.to_i]
+
+ ops[opc] &= oprs.map{|opr|opr == a ? 1 : 0}.join.to_i(2)
+end
+
+(0..15).each do |opc|
+ puts "#{opc}: #{oprsorder[ops[opc]]}"
+end