diff --git a/2019/ruby/computer.rb b/2019/ruby/computer.rb
index 9c0e7ac..5842070 100644
--- a/2019/ruby/computer.rb
+++ b/2019/ruby/computer.rb
@@ -83,14 +83,14 @@ class Computer
@rb = T.let(0, Integer)
end
- sig {params(input: AnyIO, output: AnyIO).returns(Memory)}
+ sig {params(input: T.untyped, output: AnyIO).returns(Memory)}
def run(input=STDIN, output=STDOUT)
each(input, output).inject(nil) {|_,i| i }
end
sig {
params(
- input: AnyIO,
+ input: T.untyped,
output: AnyIO,
blk: T.nilable(T.proc.params(m: Memory).returns(T.nilable(Integer)))
).returns(T::Enumerator[Memory])
diff --git a/2019/ruby/day_11.rb b/2019/ruby/day_11.rb
index 49cf6da..8deea09 100644
--- a/2019/ruby/day_11.rb
+++ b/2019/ruby/day_11.rb
@@ -1,3 +1,5 @@
+# typed: ignore
+
require "stringio"
require_relative "computer"
diff --git a/2019/ruby/day_12.rb b/2019/ruby/day_12.rb
index 76ef919..6c9f38a 100644
--- a/2019/ruby/day_12.rb
+++ b/2019/ruby/day_12.rb
@@ -1,3 +1,5 @@
+# typed: ignore
+
require "matrix"
require "prime"
require "set"
diff --git a/2019/ruby/day_13.rb b/2019/ruby/day_13.rb
new file mode 100644
index 0000000..8a217d8
--- /dev/null
+++ b/2019/ruby/day_13.rb
@@ -0,0 +1,103 @@
+# typed: ignore
+
+require "stringio"
+
+require_relative "computer"
+
+class Game
+ def initialize
+ @output = Hash.new(0)
+ @min_x, @max_x, @min_y, @max_y = 0, 0, 0, 0
+ end
+
+ def []=(x, y, value)
+ @output[[x, y]] = value
+
+ @min_x = [@min_x, x].min
+ @max_x = [@max_x, x].max
+ @min_y = [@min_y, y].min
+ @max_y = [@max_y, y].max
+ end
+
+ def ball_pos
+ @output.key(4)
+ end
+
+ def paddle_pos
+ @output.key(3)
+ end
+
+ def score
+ @output[[-1, 0]]
+ end
+
+ def to_s
+ min_x = [0, @min_x].max
+
+ screen = (@min_y..@max_y).map {|y|
+ (min_x..@max_x).map {|x|
+ tile(@output[[x, y]])
+ }.join
+ }.join("\n")
+
+ score = @output[[-1, 0]] || 0
+
+ "#{screen}\n#{score}"
+ end
+
+ private
+
+ def tile(id)
+ case id
+ when 0 then " "
+ when 1 then ?█
+ when 2 then ?▒
+ when 3 then ?▄
+ when 4 then ?@
+ else fail "unexpected tile id: #{id}"
+ end
+ end
+end
+
+class FollowBall
+ def initialize(game)
+ @game = game
+ @last_ball = nil
+ end
+
+ def gets
+ ball, paddle = nil, nil
+ until [ball, paddle].none?(&:nil?) && ball != @last_ball
+ ball = @game.ball_pos
+ paddle = @game.paddle_pos
+ end
+ @last_ball = ball
+
+ # puts @game
+
+ # STDIN.gets
+ ball[0] <=> paddle[0]
+ end
+end
+
+game = Game.new
+follow_ball = FollowBall.new(game)
+output, output_writer = IO.pipe
+
+Thread.new do
+ loop do
+ x, y, tile_id = 3.times.map { output.gets.to_i }
+ game[x, y] = tile_id
+ end
+end
+
+Thread.new do
+ program = File.read("day_13.txt").split(?,).map(&:to_i)
+ program[0] = 2
+
+ Computer.new(program).run(follow_ball, output_writer)
+
+ sleep 1
+
+ puts game.score
+end.join