From 14063c8ad4af90b27d5174ca72dd129a25dd43a1 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Sat, 2 Dec 2017 22:08:13 -0800 Subject: [PATCH] [2017][ruby][3.0] --- 2017/ruby/day_03.rb | 115 +++++++++++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 33 deletions(-) diff --git a/2017/ruby/day_03.rb b/2017/ruby/day_03.rb index b3ce809..a4139af 100644 --- a/2017/ruby/day_03.rb +++ b/2017/ruby/day_03.rb @@ -1,40 +1,89 @@ -input = ARGF.read.to_i - -dir = [1,0] - -def next_dir(dir) - case dir - when [1,0] - [0,1] - when [0,1] - [-1,0] - when [-1,0] - [0,-1] - when [0,-1] - [1,0] - else - raise "invalid dir: #{dir}" +require "minitest" + +class Spiral + def initialize + @square = [0,0] + @dir = [1,0] + @steps = [1, 1] + end + + def each + return enum_for(__method__) unless block_given? + + loop do + yield @square + step! + end + end + + private + + def step! + @steps[0] -= 1 + @square = @square.zip(@dir).map {|i,j| i+j } + if @steps[0] == 0 + change_dir! + @steps << next_steps + @steps.shift + end end -end -grid = Hash.new(0) -grid[[0,0]] = 1 + def change_dir! + @dir = case @dir + when [1,0] + [0,1] + when [0,1] + [-1,0] + when [-1,0] + [0,-1] + when [0,-1] + [1,0] + else + raise "invalid dir: #@dir" + end + end -def next_value(grid, x, y) - [[-1, 1],[0, 1],[1,1], - [-1, 0], [1,0], - [-1,-1],[0,-1],[1,-1]].map {|i,j| grid[[x+i,y+j]]}.sum + def next_steps + case @dir + when [1,0] + @steps[1] + when [0,1] + @steps[1] + 1 + when [-1,0] + @steps[1] + when [0,-1] + @steps[1] + 1 + else + raise "invalid dir: #@dir" + end + end end -current = [0,0] -loop do - next_square = current.zip(dir).map {|a,b| a + b } - value = next_value(grid, *next_square) - puts "#{current}: #{value}" - exit if value > input - grid[next_square] = value - current = next_square - dir = next_dir(dir) if grid[current.zip(next_dir(dir)).map {|a,b| a + b }] == 0 +if $0 == __FILE__ + if ARGV.shift == "test" + require "minitest/test" + else + input = ARGF.read.to_i + p Spiral.new.each.with_index.find {|_,i| i == input - 1 }.first.sum + end end -p next_value(grid, 1,0) +class TestSpiral < Minitest::Test + def test_spiral + spiral = Spiral.new + e = spiral.each + assert_equal [0,0], e.next + assert_equal [1,0], e.next + assert_equal [1,1], e.next + assert_equal [0,1], e.next + assert_equal [-1,1], e.next + assert_equal [-1,0], e.next + assert_equal [-1,-1], e.next + assert_equal [0,-1], e.next + assert_equal [1,-1], e.next + assert_equal [2,-1], e.next + + spiral = Spiral.new + assert_equal [0,-2], spiral.each.with_index.find {|_,i| i == 22 }.first + end +end