parent
f5f071aef9
commit
e008591ae7
@ -0,0 +1,233 @@
|
|||||||
|
require "minitest"
|
||||||
|
require "minitest/pride"
|
||||||
|
|
||||||
|
class Area
|
||||||
|
def self.parse(input)
|
||||||
|
acres = input.chomp.lines.map {|row| row.chomp.chars.to_a }
|
||||||
|
new(acres)
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :acres
|
||||||
|
|
||||||
|
def initialize(acres)
|
||||||
|
@acres = acres
|
||||||
|
end
|
||||||
|
|
||||||
|
def changes
|
||||||
|
return enum_for(__method__) unless block_given?
|
||||||
|
|
||||||
|
loop do
|
||||||
|
yield self
|
||||||
|
|
||||||
|
acres = @acres.map.with_index {|row, y|
|
||||||
|
row.map.with_index {|acre, x|
|
||||||
|
adjacent = self.adjacent(x, y)
|
||||||
|
case self[x, y]
|
||||||
|
when ?.
|
||||||
|
(adjacent.count(?|) >= 3) ? ?| : ?.
|
||||||
|
when ?|
|
||||||
|
(adjacent.count(?#) >= 3) ? ?# : ?|
|
||||||
|
when ?#
|
||||||
|
(adjacent.count(?#) >= 1 && adjacent.count(?|) >= 1) ? ?# : ?.
|
||||||
|
else
|
||||||
|
fail "Unexpected acre: #{self[x, y]}"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@acres = acres
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
@acres.map {|row| row.join }.join(?\n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](x, y)
|
||||||
|
@acres.fetch(y).fetch(x)
|
||||||
|
end
|
||||||
|
|
||||||
|
def adjacent(x, y)
|
||||||
|
(-1..1).flat_map {|dx| (-1..1).map {|dy| [dx, dy] } }
|
||||||
|
.reject {|dx,dy| dx == 0 && dy == 0 }
|
||||||
|
.map {|dx, dy| [x+dx, y+dy] }
|
||||||
|
.reject {|x, y| x < 0 || y < 0 }
|
||||||
|
.map {|x, y|
|
||||||
|
@acres.fetch(y) { [] }.fetch(x) { nil }
|
||||||
|
}.compact
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class TestArea < Minitest::Test
|
||||||
|
def test_area
|
||||||
|
area = Area.parse(<<~AREA)
|
||||||
|
.#.#...|#.
|
||||||
|
.....#|##|
|
||||||
|
.|..|...#.
|
||||||
|
..|#.....#
|
||||||
|
#.#|||#|#|
|
||||||
|
...#.||...
|
||||||
|
.|....|...
|
||||||
|
||...#|.#|
|
||||||
|
|.||||..|.
|
||||||
|
...#.|..|.
|
||||||
|
AREA
|
||||||
|
changes = area.changes
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
.#.#...|#.
|
||||||
|
.....#|##|
|
||||||
|
.|..|...#.
|
||||||
|
..|#.....#
|
||||||
|
#.#|||#|#|
|
||||||
|
...#.||...
|
||||||
|
.|....|...
|
||||||
|
||...#|.#|
|
||||||
|
|.||||..|.
|
||||||
|
...#.|..|.
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
.......##.
|
||||||
|
......|###
|
||||||
|
.|..|...#.
|
||||||
|
..|#||...#
|
||||||
|
..##||.|#|
|
||||||
|
...#||||..
|
||||||
|
||...|||..
|
||||||
|
|||||.||.|
|
||||||
|
||||||||||
|
||||||
|
....||..|.
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
.......#..
|
||||||
|
......|#..
|
||||||
|
.|.|||....
|
||||||
|
..##|||..#
|
||||||
|
..###|||#|
|
||||||
|
...#|||||.
|
||||||
|
|||||||||.
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
.|||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
.......#..
|
||||||
|
....|||#..
|
||||||
|
.|.||||...
|
||||||
|
..###|||.#
|
||||||
|
...##|||#|
|
||||||
|
.||##|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
.....|.#..
|
||||||
|
...||||#..
|
||||||
|
.|.#||||..
|
||||||
|
..###||||#
|
||||||
|
...###||#|
|
||||||
|
|||##|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
....|||#..
|
||||||
|
...||||#..
|
||||||
|
.|.##||||.
|
||||||
|
..####|||#
|
||||||
|
.|.###||#|
|
||||||
|
|||###||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
...||||#..
|
||||||
|
...||||#..
|
||||||
|
.|.###|||.
|
||||||
|
..#.##|||#
|
||||||
|
|||#.##|#|
|
||||||
|
|||###||||
|
||||||
|
||||#|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
...||||#..
|
||||||
|
..||#|##..
|
||||||
|
.|.####||.
|
||||||
|
||#..##||#
|
||||||
|
||##.##|#|
|
||||||
|
|||####|||
|
||||||
|
|||###||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
..||||##..
|
||||||
|
..|#####..
|
||||||
|
|||#####|.
|
||||||
|
||#...##|#
|
||||||
|
||##..###|
|
||||||
|
||##.###||
|
||||||
|
|||####|||
|
||||||
|
||||#|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
..||###...
|
||||||
|
.||#####..
|
||||||
|
||##...##.
|
||||||
|
||#....###
|
||||||
|
|##....##|
|
||||||
|
||##..###|
|
||||||
|
||######||
|
||||||
|
|||###||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
|
||||||
|
assert_equal <<~AREA.chomp, changes.next.to_s
|
||||||
|
.||##.....
|
||||||
|
||###.....
|
||||||
|
||##......
|
||||||
|
|##.....##
|
||||||
|
|##.....##
|
||||||
|
|##....##|
|
||||||
|
||##.####|
|
||||||
|
||#####|||
|
||||||
|
||||#|||||
|
||||||
|
||||||||||
|
||||||
|
AREA
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def solve(input)
|
||||||
|
area = Area.parse(input)
|
||||||
|
area = area.changes.lazy.drop(10).first
|
||||||
|
wooded = area.acres.flat_map(&:itself).count(?|)
|
||||||
|
lumberyards = area.acres.flat_map(&:itself).count(?#)
|
||||||
|
wooded * lumberyards
|
||||||
|
end
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
|
require "minitest/autorun" and exit if ENV["TEST"]
|
||||||
|
|
||||||
|
puts solve(ARGF.read)
|
||||||
|
end
|
Loading…
Reference in new issue