Skip to content

Instantly share code, notes, and snippets.

@robpe
Created September 5, 2017 16:17
Show Gist options
  • Save robpe/e1704441e044ffda37e9a05972e9f356 to your computer and use it in GitHub Desktop.
Save robpe/e1704441e044ffda37e9a05972e9f356 to your computer and use it in GitHub Desktop.
Shortest path in grid with tunnels and jumps
def neighbours(grid, pos)
x, y = pos
[[x-1, y], [x+1, y], [x, y-1], [x, y+1]].select do |i, j|
i > 0 && i < grid.first.size && j > 0 && j < grid.size && grid[j][i] == 0
end
end
def jump_neighbours(grid, pos)
x, y = pos
width, height = grid.first.size, grid.size
n = []
n << [x-2, y] if x-2 > 0 && grid[y][x-1] == 1 && grid[y][x-2] == 0
n << [x+2, y] if x+2 < width && grid[y][x+1] == 1 && grid[y][x+2] == 0
n << [x, y-2] if y-2 > 0 && grid[y-1][x] == 1 && grid[y-2][x] == 0
n << [x, y+2] if y+2 < height && grid[y+1][x] == 1 && grid[y+2][x] == 0
n
end
def shortest_path(grid, s, e, jumps)
paths = []
(dfs = lambda do |s, jumps, path|
if s == e
paths << path + [e]
else
x, y = s
neighbours(grid, s).each do |v|
dfs.call(v, jumps, path+[s]) unless path.include?(v)
end
if jumps > 0
jump_neighbours(grid, s).each do |v|
dfs.call(v, jumps-1, path+[s]) unless path.include?(v)
end
end
end
end
).call(s, jumps, [])
paths.sort_by(&:size).first
end
grid = [
[1, 0, 1, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 0, 1]
]
p shortest_path(grid, [1,0], [3,2], 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment