diff --git a/2016/ruby/day_08.rb b/2016/ruby/day_08.rb
new file mode 100644
index 0000000..3fbef3a
--- /dev/null
+++ b/2016/ruby/day_08.rb
@@ -0,0 +1,85 @@
+class Screen
+ attr_reader :width, :height, :pixels
+
+ def initialize(width, height)
+ @width, @height = width, height
+ @pixels = Array.new(height) { Array.new(width, false) }
+ end
+
+ def to_s
+ pixels.map {|row| row.map {|pixel| pixel ? ?# : ?. }.join }.join("\n")
+ end
+
+ def <<(instruction)
+ case instruction
+ when /rect (\d+)x(\d+)/
+ $1.to_i.times do |x|
+ $2.to_i.times do |y|
+ pixels[y][x] = true
+ end
+ end
+ when /rotate column x=(\d+) by (\d+)/
+ col = pixels.map {|row| row[$1.to_i] }.rotate(-$2.to_i)
+ pixels.each do |row|
+ row[$1.to_i] = col.shift
+ end
+ when /rotate row y=(\d+) by (\d+)/
+ row = pixels[$1.to_i].rotate(-$2.to_i)
+ pixels[$1.to_i] = row
+ end
+ end
+end
+
+if __FILE__ == $0
+ screen = Screen.new(50, 6)
+ DATA.lines.each do |line|
+ screen << line
+ end
+
+ puts screen
+ puts screen.pixels.map {|row| row.count {|pixel| pixel }}.inject(:+)
+end
+
+require 'minitest'
+# require 'minitest/autorun'
+
+class TestScreen < Minitest::Test
+ def test_screen
+ screen = Screen.new(7, 3)
+ assert_equal <<-PIXELS.chomp, screen.to_s
+.......
+.......
+.......
+ PIXELS
+
+ screen << 'rect 3x2'
+ assert_equal <<-PIXELS.chomp, screen.to_s
+###....
+###....
+.......
+ PIXELS
+
+ screen << 'rotate column x=1 by 1'
+ assert_equal <<-PIXELS.chomp, screen.to_s
+#.#....
+###....
+.#.....
+ PIXELS
+
+ screen << 'rotate row y=0 by 4'
+ assert_equal <<-PIXELS.chomp, screen.to_s
+....#.#
+###....
+.#.....
+ PIXELS
+
+ screen << 'rotate column x=1 by 1'
+ assert_equal <<-PIXELS.chomp, screen.to_s
+.#..#.#
+#.#....
+.#.....
+ PIXELS
+ end
+end
+
+__END__