diff --git a/2016/ruby/day_10.rb b/2016/ruby/day_10.rb new file mode 100644 index 0000000..3cebadb --- /dev/null +++ b/2016/ruby/day_10.rb @@ -0,0 +1,343 @@ +class Factory + attr_reader :bots, :bins + + def initialize + @bots = Hash.new {|h,k| h[k] = Bot.new(self) } + @bins = Hash.new {|h,k| h[k] = Bin.new } + end + + def <<(instruction) + case instruction + when /value (\d+) goes to bot (\d+)/ + bots[$2.to_i] << $1.to_i + when /bot (\d+) gives low to (.+) (\d+) and high to (.+) (\d+)/ + bot = bots[$1.to_i] + bot.outs = [out($2, $3.to_i), + out($4, $5.to_i)] + else + raise "invalid instruction: #{instruction}" + end + end + + private + + def out(type, id) + case type + when 'bot' + bots[id] + when 'output' + bins[id] + else + raise "invalid type: #{type}" + end + end +end + +class Bot + attr_reader :factory, :values, :outs, :log + + def initialize(factory) + @factory = factory + @values = [] + @log = [] + end + + def <<(value) + values << value + try_run + end + + def outs=(outs) + @outs = outs + try_run + end + + private + + def try_run + return unless outs && values.size == 2 + + log << values.sort + + low, high = values.sort + values.clear + + outs[0] << low + outs[1] << high + end +end + +class Bin + attr_reader :value + + def <<(value) + @value = value + end +end + +if __FILE__ == $0 + factory = Factory.new + DATA.each_line do |line| + factory << line + end + + p factory.bots.find {|id, bot| + bot.log.include?([17, 61]) + }.first +end + +require 'minitest' +# require 'minitest/autorun' + +class TestDay10 < Minitest::Test + def test_day_10 + instructions = <