1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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__