[2024][ruby][16.1]

main
Alpha Chen 6 days ago
parent 40b917bc31
commit 18daaa3e49
Signed by: alpha
SSH Key Fingerprint: SHA256:3fOT8fiYQG/aK9ntivV3Bqtg8AYQ7q4nV6ZgihOA20g

@ -0,0 +1,62 @@
tiles = DATA.readlines(chomp: true).flat_map.with_index {|row, y|
row.chars.filter_map.with_index {|tile, x|
tile == ?# ? nil : [[y,x], tile]
}
}.to_h
start, stop = %w[ S E ].map {|t| tiles.find { _2 == t }[0] }
scores = Hash.new(Float::INFINITY)
scores[[start, [0,1]]] = 0
queue = [[start, [0,1]]]
visited = Set.new
loop do
fail if queue.empty?
current, dir = queue.shift
visited << [current, dir]
score = scores.fetch([current, dir])
break if current == stop
# straight ahead
yx = current.zip(dir).map { _1 + _2 }
if tiles.has_key?(yx)
scores[[yx, dir]] = [scores[[yx, dir]], score + 1].min
queue << [yx, dir] unless visited.include?([yx, dir])
end
# sides
[-1, 1].each do |d|
delta = dir.reverse.zip([d, d]).map { _1 * _2 }
yx = current.zip(delta).map { _1 + _2 }
if tiles.has_key?(yx)
scores[[yx, delta]] = [scores[[yx, delta]], score + 1001].min
queue << [yx, delta] unless visited.include?([yx, delta])
end
end
queue.uniq!
queue.sort_by! { scores.fetch(_1) }
end
pp scores.find {|(yx,_),_| yx == stop }[1]
__END__
#################
#...#...#...#..E#
#.#.#.#.#.#.#.#^#
#.#.#.#...#...#^#
#.#.#.#.###.#.#^#
#>>v#.#.#.....#^#
#^#v#.#.#.#####^#
#^#v..#.#.#>>>>^#
#^#v#####.#^###.#
#^#v#..>>>>^#...#
#^#v###^#####.###
#^#v#>>^#.....#.#
#^#v#^#####.###.#
#^#v#^........#.#
#^#v#^#########.#
#S#>>^..........#
#################
Loading…
Cancel
Save