You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
require 'digest/md5'
|
|
|
|
|
|
|
|
State = Struct.new(:location, :path)
|
|
|
|
|
|
|
|
Maze = Struct.new(:passcode, :size) do
|
|
|
|
def walk
|
|
|
|
return enum_for(__method__) unless block_given?
|
|
|
|
|
|
|
|
states = [State.new([0,0], '')]
|
|
|
|
until states.empty?
|
|
|
|
state = states.shift
|
|
|
|
yield state
|
|
|
|
|
|
|
|
next if state.location == [3,3]
|
|
|
|
|
|
|
|
hash = Digest::MD5.hexdigest("#{passcode}#{state.path}")[0,4]
|
|
|
|
open_doors = %i[ U D L R ].select.with_index {|_, index|
|
|
|
|
'bcdef'.include?(hash[index])
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
U: [ 0, -1],
|
|
|
|
D: [ 0, 1],
|
|
|
|
L: [-1, 0],
|
|
|
|
R: [ 1, 0],
|
|
|
|
}.select {|door, _|
|
|
|
|
open_doors.include?(door)
|
|
|
|
}.map {|door, (dx, dy)|
|
|
|
|
x = state.location[0] + dx
|
|
|
|
y = state.location[1] + dy
|
|
|
|
|
|
|
|
location = [x, y]
|
|
|
|
path = state.path + door.to_s
|
|
|
|
State.new(location, path)
|
|
|
|
}.select {|state|
|
|
|
|
state.location.all? {|i| (0...size).cover?(i) }
|
|
|
|
}.each do |state|
|
|
|
|
states << state
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
p Maze.new('yjjvjgan', 4).walk.select {|state|
|
|
|
|
state.location == [3, 3]
|
|
|
|
}.map(&:path).map(&:length).max
|