|
|
|
require "minitest"
|
|
|
|
|
|
|
|
class Spiral
|
|
|
|
def initialize
|
|
|
|
@state = [0,0]
|
|
|
|
end
|
|
|
|
|
|
|
|
def each
|
|
|
|
return enum_for(__method__) unless block_given?
|
|
|
|
|
|
|
|
(1..Float::INFINITY).lazy
|
|
|
|
.flat_map {|i| [i, i] }
|
|
|
|
.zip(%i[r u l d].cycle)
|
|
|
|
.flat_map {|n,d| Array.new(n, d) }
|
|
|
|
.each do |dir|
|
|
|
|
|
|
|
|
yield @state
|
|
|
|
@state = @state.zip(
|
|
|
|
case dir
|
|
|
|
when :r
|
|
|
|
[1, 0]
|
|
|
|
when :u
|
|
|
|
[0, 1]
|
|
|
|
when :l
|
|
|
|
[-1, 0]
|
|
|
|
when :d
|
|
|
|
[0, -1]
|
|
|
|
end
|
|
|
|
).map {|a,b| a + b }
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
class Grid
|
|
|
|
def initialize
|
|
|
|
@grid = Hash.new {|h,(x,y)|
|
|
|
|
neighbors = [[-1, 1], [0, 1], [1, 1],
|
|
|
|
[-1, 0], [1, 0],
|
|
|
|
[-1,-1], [0,-1], [1,-1]]
|
|
|
|
h[[x,y]] = neighbors
|
|
|
|
.map {|i,j| [x+i,y+j] }
|
|
|
|
.select {|i,j| h.has_key?([i,j]) }
|
|
|
|
.map {|i,j| h[[i,j]] }
|
|
|
|
.sum
|
|
|
|
}
|
|
|
|
@grid[[0,0]] = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
def [](x,y)
|
|
|
|
@grid[[x,y]]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if $0 == __FILE__
|
|
|
|
case ARGV.shift
|
|
|
|
when "test"
|
|
|
|
require "minitest/autorun"
|
|
|
|
when "0"
|
|
|
|
input = ARGF.read.to_i
|
|
|
|
p Spiral.new.each.with_index.find {|_,i| i == input - 1 }.first.sum
|
|
|
|
when "1"
|
|
|
|
input = ARGF.read.to_i
|
|
|
|
grid = Grid.new
|
|
|
|
p Spiral.new.each.lazy.map {|x,y| grid[x,y] }.find {|value| value > input }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
class TestGrid < Minitest::Test
|
|
|
|
def test_grid
|
|
|
|
grid = Grid.new
|
|
|
|
assert_equal 1, grid[0,0]
|
|
|
|
assert_equal 1, grid[1,0]
|
|
|
|
assert_equal 2, grid[1,1]
|
|
|
|
assert_equal 4, grid[0,1]
|
|
|
|
assert_equal 5, grid[-1,1]
|
|
|
|
assert_equal 10, grid[-1,0]
|
|
|
|
end
|
|
|
|
end
|