diff --git a/2016/ruby/day_10.rb b/2016/ruby/day_10.rb
new file mode 100644
index 0000000..6a9ab73
--- /dev/null
+++ b/2016/ruby/day_10.rb
@@ -0,0 +1,112 @@
+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 = <<INSTRUCTIONS
+value 5 goes to bot 2
+bot 2 gives low to bot 1 and high to bot 0
+value 3 goes to bot 1
+bot 1 gives low to output 1 and high to bot 0
+bot 0 gives low to output 2 and high to output 0
+value 2 goes to bot 2
+INSTRUCTIONS
+
+ factory = Factory.new
+ instructions.lines.each do |line|
+ factory << line
+ end
+
+ assert_equal [5, 2, 3], factory.bins.sort_by {|k,_| k }.map(&:last).map(&:value)
+ end
+end
+
+__END__