parent
570745e381
commit
2141980e12
@ -0,0 +1,39 @@
|
|||||||
|
#########################################################################################################################################################################################
|
||||||
|
#...#...............#.#...#.#.......#.....#.....#.....#...............#.....#.#.....#.....#.......#.........#.#.....#.....#.#.#...#...........#.................#.#...#.....#.....#...#.#
|
||||||
|
#.###.#.###.###.###.#.###.#.###.#####.###.#.#.#.#.#.#.#.#.###.#.#####.#.#.#.#.#.#.###.###.#.#.#.#.###.###.#.#.#.#.###.###.#.#.#.#.#####.#####.#.#.###########.###.#.#.#.###.#.###.#.#.#.#
|
||||||
|
#.#...#.....#.....#.#.#...#.#.....#.#.#...#.....#.#.#.....#.............#...#.....#...#.#.........#.#.....#.......#...#.#.#.#.#.........#.....#.#.#...#...#...#...#...#.....#.....#...#.#
|
||||||
|
#.#.###.#.#.#.#.###.#.#.###.#.#####.#.#.#.#.#####.#.#.#.###.#.#.#.#.###.#.#.###.#.#.#.#.###.###.#.#.###.#.#.#.###.###.#.#.#.#.###########.#.###.#.###.#.#.#.#.#.#.#.#.###.#.#.#.###.#.#.#
|
||||||
|
#...........#.#.#...#.#.....#.....#...........#...........#.....#.............#.......#.#...............#.....#.......#.....#...............#1....#.......#.#.....#.......#...#.....#...#
|
||||||
|
#.###.#.#.#.#.#.#.#.#########.#.#.#.#.#.###.#.#.#####.#.#.#.###.#.###.#########.#######.#.#.#.#.#############.#####.#.###.#.#.#.#.#####.#.#######.#####.#.#.#.#.#.#####.#.#.#.#.###.#.###
|
||||||
|
#...#.....#.....#.#.#.#.................#.#.#...#.......#...#...#.#...........#.#...#.......#.#.#...#...#.......#...#.#.#.#.#.....#.....#.....#.......#...#...#...#.......#...#.....#...#
|
||||||
|
#.#.#####.#.#####.#.#.#.#.###.###.#.#.###.#.#.#.#.#######.#.#.#.#.###.#.###.#####.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#######.#.#####.#.#.#.#######.#.#.#.#.#.#######.#.###.#.#.#.###.###.#.#.#
|
||||||
|
#...#.....#.......#.#...#.#...#...........#...#...#.#.....#...#.......#.......#.#.#.#...#.#.....#.#...#...#.....#.........#...#.........#.#.....#.....#...#.#.#...#...#.....#.#3#.#.....#
|
||||||
|
#.#.###.#.#.###.#######.#.#.#.#.###.###.#####.#.#.#.#.#.#.#.#.#.#####.#.###.###.###.#.#.#.#.#.#.#.###.#.#######.###.#.###.#.#.#.###.#.#.#.#.#.#.#.#.###.###.#.#.###.#.#.###.#.#.#.###.#.#
|
||||||
|
#.......#.#...#.#.#.....#...#...#0..#.#.....#.#.....#.#.#...#...#.....#.....#.#.....#...#.#...#.#...#.#.#...#...#...#...#.#.#.............#.#...#.......#...#...#...#.#.#.....#...#.#...#
|
||||||
|
#####.#####.#.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#.###.#.###.#.#.#.#.#.#.###.###.###.#.#####.#####.#.#.#.#.#.#.#.#.#.#.#.###.#.###.###########.#.#.#########.#.#.#.#.###.#.###.#.###.#.#.#.#
|
||||||
|
#...#...#.......#.#.#...#.......#...#...#.#...#.#...#.....#.....#.....#.#.#.........#.#.......#...#.#...#.#.........#...#.........#...#...#.#.....#.....#...#.#.......#.#.....#.........#
|
||||||
|
#.#.###.#.#####.###.###.#.#.###.###.#.###.#.#.#.#.#.#.#####.#.###.#.#.#.###.###.#####.#.#.#.#.#.###.###.#.#########.#.###.#.#.#.#.#.#.#.#.#.#####.###.#.#.#.#.#.#.#.#.#####.#.###.#.###.#
|
||||||
|
#.....#.#.#...#.#...#.#.....#.#...........#.....#...#.#...#.#.....#.#.#.....#.......#...#.#.#.......#.......#.........#.........#.#.#.#...#...#.#...#...#.......#.....#.....#.......#...#
|
||||||
|
###.#.#.#####.#.#.#.#.#.#.#.#.#.#.#.#.#.#######.###.#.#####.#####.###.#.#.#.###.#.#.###.#.#.#.#.#####.#.###.#.#.#.#########.#.###.#.#.#.#.#####.###.#.#.#.###.#####.#.#.#.#.#.#.#.#.#.###
|
||||||
|
#.#...#.#.......#.#.#...#.......#.#.....#.#.........#...#.....#.................#.........#...#...#.#...#.....#...#...#.#...#...#...#.....#...#.......#.......#.....#...#...#...#...#.#.#
|
||||||
|
#.#.#####.#.#####.###.#.###.#.###.#.#.#.#.#######.#.###.###.#.#.#########.#.###.#########.###.###.#.###.#.#####.#.###.#.#.#.#.#.#.#.#.###.#.#.#.#########.#####.#.#.###.#.#.#.#.#####.#.#
|
||||||
|
#.............#2#.#.....#.#.#...#...#.#...........#.........#...#.#.......#.#.........#.#.#.....#.#.......#...#.....#...#.#.#.......#...#.#.......#.......#...#.........#...#...#.....#.#
|
||||||
|
#.#.###.#.#.#.#.#.#.#.###.#.###.#.#####.###.###.#.#.#.#.#.#.#####.#.#.#.#.###.#.#####.#.#.#.#.#####.#.#####.###.###.#.#.#.#.#.#.#.#.#.#.#.#.###.#.###.#####.#######.#.#.#####.###.###.#.#
|
||||||
|
#...#...#...#...#.#.#.#...#.#.........#.#.#...............#.#...#...#.....#...#.#...#...#...........#.#.....#.....#...#.#.#...#...#.#.....#.....#...........#...#.....#.....#.#6#.....#.#
|
||||||
|
#####.#.#####.###.#.#.#.#.#.###.###.#.###.#.#########.#.###.#.#.#.###.###.#####.#####.###.###.#.#.#.###.#.#.#.#.###.#.###.#.#.#.#.###.#.#.#.###.#.#.#.#.#.###.#.#####.#.###.#.#.#.###.#.#
|
||||||
|
#...#...#.....#.....#...#...#...#.....#.....................#...#.....#.........#.....#.#.#...#.#.........#.....................#...#...#.....#...#...#.....#...#...#.....#.#.......#...#
|
||||||
|
#.###.#.#.#.#.###.#.###.#.#####.#.###.#.#####.#.#######.#.#.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#####.###.#####.#######.###.#.#.#######.###.#.###.###.#.#.###.#.#.#.#####.#.#.#######.#
|
||||||
|
#.#...#.........#...#.....#.......#.....#.#.....#.#...#.#...#.#...#.........#.....#.......#.......#.......#.......#...#...#.......#.....#.#...........#.........#.#.#...#.#.#.....#...#.#
|
||||||
|
#.#.#.#.#.#.#.#.#.#.#########.#####.#.###.#.#####.#.###.#.#.#.#.#########.#.#.#.#.###.###.#####.###.###.#.#.#.#####.#.#.#########.###.#.###.###.###.#.#######.#.###.###.#.###.###.#.###.#
|
||||||
|
#.....#.....#...#.#.........#...#.....#...#.............#.....#.#.........#...#.......#.................#...#.........#...#...........#.........#.....#.......#.....#.....#.#.#.#...#.#.#
|
||||||
|
#.###.#.###.#.#.#.#.#.#.#.###.###.#.#######.#.###.#####.#.###.#.#.#.#.#.#.#.#.#######.###.###.#######.#.###.###.#####.#.#.#.#.#.#.#.###.#.###.###.###.#.###.#.###.###.#####.#.#.###.#.###
|
||||||
|
#.....#...#.#.....#.#...#.....#.....#.#...#...#...........#.#.#...........#.#.#.....#.....#...#...#...#...#.....#.......#.......#.#.........#.....#.....#.#...#.......#.........#.......#
|
||||||
|
#.#.#.###.#.#.#.###.###.#.###.#####.#.#.#.#.#.#######.###.#.#.#.#####.###.#.#.###.###.#.#.#.#.#.###.#####.###.###.#######.###.#.#.#.#.#.#.#####.#########.#.#.#.#.#.###.#######.###.#.#.#
|
||||||
|
#.......#.#.#.....#.....#.#...#.....#...#.#.....#...#.#...#.....#.......#...#.#.#...#.....#.......#.......#...#.#.......#...#...#.#.#...#.......#.....#.#...#.#.#...#...#.......#.......#
|
||||||
|
#.###.###.#.#.###.#.#.#.#.#.#.#.#.#.###.###.#.#.###.#.###.###.#.#.#.#.#.#####.#.#.#.#.#.#########.#.###.#.#.#.#.#.#.#.#.#.#####.###.###.#.#.#.#.#.#.#.#.#.#.###.#.###.#.#####.#######.#.#
|
||||||
|
#.....#.#5......#.......#...#.#.#...#.#.#.#.....#.....#.#.....#.......#.#...#...#.....#.....#...........#...#.......#.#...#.........#.........#.........#...........#.#.#.....#7....#.#.#
|
||||||
|
#.#.#.#.###.#####.#####.#.###.#.#.#.#.###.#.#.#.#####.#.#.#.#.#.###.#.###.###.###.#.#.###.#.#.#.#.#######.#.#.#####.#.#.###.#.#####.#.#.#.#.#.#.#.#####.#.#.#.#.#####.#.#.#.#.#####.#.#.#
|
||||||
|
#...........#.#...#.........#...#.#.#.#.......#.#.....#...#...#.#.....#...#...#.......#.................................#...#...#.#.....#.....#...#...#.#...#...#.#.......#.........#.#.#
|
||||||
|
###.###.#.###.#.###.#.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#.#.###.###.###.###.#.###.#.###.#####.#.#.###.###.#.#####.#.#.#.#####.#.###.#.#.#.#.###.#.###.###.#.#######.#.#.#.#.###.###.#.#.#.#.#
|
||||||
|
#.......#.#.........#...#.#.#.................#.......#...#.....#...............#...#.#...#...#.......#.#.#.......#.......#...............#4#.......#.....#...#...#.#...#.......#.....#.#
|
||||||
|
#########################################################################################################################################################################################
|
@ -0,0 +1,130 @@
|
|||||||
|
class Solver
|
||||||
|
def initialize(maze)
|
||||||
|
@maze = maze
|
||||||
|
end
|
||||||
|
|
||||||
|
def solve(from, to)
|
||||||
|
seen = Set.new(from)
|
||||||
|
queue = [[from, 0]]
|
||||||
|
current = queue.shift
|
||||||
|
|
||||||
|
loop do
|
||||||
|
location = current[0]
|
||||||
|
break if location == to
|
||||||
|
|
||||||
|
seen << location
|
||||||
|
|
||||||
|
neighbors = maze
|
||||||
|
.open_neighbors(location[0], location[1])
|
||||||
|
.reject {|location| seen.include?(location) }
|
||||||
|
|
||||||
|
queue.concat(neighbors.map {|location| [location, current[1] + 1] })
|
||||||
|
|
||||||
|
return nil if queue.empty?
|
||||||
|
current = queue.shift
|
||||||
|
end
|
||||||
|
|
||||||
|
current[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :maze
|
||||||
|
end
|
||||||
|
|
||||||
|
class Maze
|
||||||
|
attr_reader :locations
|
||||||
|
|
||||||
|
def initialize(input)
|
||||||
|
@maze = Hash.new
|
||||||
|
@locations = Hash.new
|
||||||
|
|
||||||
|
x, y = 0, 0
|
||||||
|
input.chars.each do |char|
|
||||||
|
case char
|
||||||
|
when /\d/
|
||||||
|
@locations[char.to_i] = [x,y]
|
||||||
|
char = ?.
|
||||||
|
when "\n"
|
||||||
|
x = -1
|
||||||
|
y += 1
|
||||||
|
else
|
||||||
|
# no-op
|
||||||
|
end
|
||||||
|
|
||||||
|
@maze[[x,y]] = char
|
||||||
|
x += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](x,y)
|
||||||
|
maze[[x,y]]
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_neighbors(x, y)
|
||||||
|
[[-1, 0],
|
||||||
|
[ 1, 0],
|
||||||
|
[ 0, -1],
|
||||||
|
[ 0, 1]].map {|dx,dy|
|
||||||
|
[x+dx, y+dy]
|
||||||
|
}.select {|x,y|
|
||||||
|
self[x,y] == ?.
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :maze
|
||||||
|
end
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
|
maze = Maze.new(ARGF.read)
|
||||||
|
solver = Solver.new(maze)
|
||||||
|
|
||||||
|
hash = maze.locations.to_a.combination(2).each.with_object({}) {|(a, b), hash|
|
||||||
|
steps = solver.solve(a[1], b[1])
|
||||||
|
hash[[a[0],b[0]]] = steps
|
||||||
|
hash[[b[0],a[0]]] = steps
|
||||||
|
}
|
||||||
|
|
||||||
|
p maze
|
||||||
|
.locations
|
||||||
|
.map(&:first)
|
||||||
|
.permutation
|
||||||
|
.select {|route| route[0] == 0 }
|
||||||
|
.map {|route|
|
||||||
|
[route, route.each_cons(2).map {|a,b| hash[[a,b]] }.inject(:+)]
|
||||||
|
}.sort_by(&:last)
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'minitest'
|
||||||
|
# require 'minitest/autorun'
|
||||||
|
|
||||||
|
class TestMaze < Minitest::Test
|
||||||
|
def test_maze
|
||||||
|
maze = Maze.new(<<-MAZE)
|
||||||
|
###########
|
||||||
|
#0.1.....2#
|
||||||
|
#.#######.#
|
||||||
|
#4.......3#
|
||||||
|
###########
|
||||||
|
MAZE
|
||||||
|
assert_equal [1,1], maze.locations[0]
|
||||||
|
|
||||||
|
assert_equal [[2,1], [1,2]], maze.open_neighbors(1,1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class TestSolver < Minitest::Test
|
||||||
|
def test_solver
|
||||||
|
maze = Maze.new(<<-MAZE)
|
||||||
|
###########
|
||||||
|
#0.1.....2#
|
||||||
|
#.#######.#
|
||||||
|
#4.......3#
|
||||||
|
###########
|
||||||
|
MAZE
|
||||||
|
solver = Solver.new(maze)
|
||||||
|
assert_equal 2, solver.solve(maze.locations[0], maze.locations[4])
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in new issue