|
|
|
map = DATA.readlines(chomp: true).flat_map.with_index {|row, y|
|
|
|
|
row.chars.map.with_index {|height, x|
|
|
|
|
[[y,x], height == ?. ? nil : height.to_i]
|
|
|
|
}
|
|
|
|
}.to_h
|
|
|
|
|
|
|
|
trailheads = map.filter_map { _2 == 0 && _1}
|
|
|
|
|
|
|
|
DELTAS = [[-1, 0], [1, 0], [0, -1], [0, 1]]
|
|
|
|
|
|
|
|
def trails(map, head)
|
|
|
|
active = [[head]]
|
|
|
|
finished = []
|
|
|
|
until active.empty?
|
|
|
|
current = active.shift
|
|
|
|
|
|
|
|
steps = DELTAS
|
|
|
|
.map {|d| current.last.zip(d).map { _1 + _2 } }
|
|
|
|
.select { map.fetch(_1, nil) == map.fetch(current.last) + 1 }
|
|
|
|
|
|
|
|
if steps.empty?
|
|
|
|
finished << current
|
|
|
|
else
|
|
|
|
active.concat(steps.map { current + [_1] })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
finished
|
|
|
|
.select { map.fetch(_1.last) == 9 }
|
|
|
|
.uniq
|
|
|
|
end
|
|
|
|
|
|
|
|
# part one
|
|
|
|
pp trailheads.sum { trails(map, _1).map(&:last).uniq.length }
|
|
|
|
|
|
|
|
# part two
|
|
|
|
pp trailheads.sum { trails(map, _1).length }
|
|
|
|
|
|
|
|
__END__
|
|
|
|
89010123
|
|
|
|
78121874
|
|
|
|
87430965
|
|
|
|
96549874
|
|
|
|
45678903
|
|
|
|
32019012
|
|
|
|
01329801
|
|
|
|
10456732
|