Skip to content

Instantly share code, notes, and snippets.

@sarahzrf
Created December 15, 2021 06:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sarahzrf/989284c1e2928c3fb314f300f750ef72 to your computer and use it in GitHub Desktop.
Save sarahzrf/989284c1e2928c3fb314f300f750ef72 to your computer and use it in GitHub Desktop.
require 'set'
# i had to learn dijkstra's algo for this...
class Cell
def initialize(cave, x, y)
@cave = cave
@x = x
@y = y
end
attr_reader :x, :y
def risk
@cave.risk_at(x, y)
end
def neighbors
@cave.neighbors_at(x, y)
end
def unvisited?
!@cave.total_risk_at(x, y)
end
end
class Cave
def initialize(map)
@map = map
@height = map.length
@width = map[0].length
@total_risk = {}
@estimates = {[0, 0] => 0}
end
attr_reader :width, :height
def [](x, y)
Cell.new(self, x, y)
end
def risk_at(x, y)
@map[y][x]
end
def neighbors_at(x, y)
ns = []
ns << self[x - 1, y] if x > 0
ns << self[x + 1, y] if x + 1 < width
ns << self[x, y - 1] if y > 0
ns << self[x, y + 1] if y + 1 < height
ns
end
def total_risk_at(x, y)
@total_risk[[x, y]]
end
def explore
until @estimates.empty?
(x, y), tot = @estimates.min_by {|k, v| v}
@estimates.delete [x, y]
@total_risk[[x, y]] = tot
cur = self[x, y]
cur.neighbors.filter(&:unvisited?).each do |n|
thru_cur = tot + n.risk
@estimates[[n.x, n.y]] = [@estimates[[n.x, n.y]], thru_cur].compact.min
end
end
end
end
def fiveify(grid)
step1 = grid.map {|row| (0..4).flat_map {|o| row.map {|n| (n - 1) + o}}}
step2 = (0..4).flat_map {|o| step1.map {|row| row.map {|n| (n + o) % 9 + 1}}}
end
grid = $<.map {|l| l.chomp.chars.map(&:to_i)}
grid = fiveify(grid)
cave = Cave.new(grid)
cave.explore
p cave.total_risk_at(cave.width - 1, cave.height - 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment