I came across this quite interesting problem, where we have a 4x4 maze and a robot in it trying to get to the goal. The thing is, you have to find a sequence of predefined commands that will always result in the robot reaching the goal.
Let's say we have a maze like this:
x . . .
. # # .
. # # .
. . . g
This particular maze can be solved with, for example, the command sequences DDDRRR
or RRRDDD
, where R = right, L = left, U = up and D = down (duh).
Neither of those sequences would, however, solve this maze:
x . # .
. . . .
# . . .
. . . g
The robot always starts at the top left, the goal is always at the bottom right, and the maze is always a 2D 4x4 matrix.
I have already implemented an algorithm that got me a winning sequence of 78 commands. I know for sure there at least exists a solution for 29 commands (someone else accomplished this).
This problem is in fact a few years old and so I've lost the algorithm I used at the time, however the basic idea was to run a search through all the mazes I generated, and always choose the route that results in the most solved mazes. This actually got me a sequence that was slightly more than 78 in length; I reduced some commands by hand that I noticed were redundant.
Yes, brute-forcing will take years as per usual.
If my memory serves, there are less than 4000 possible mazes (possible maze being that a path between top left and bottom right exists).
OH! it's sufficient that the robot simply visits the goal at least once during the execution of the commands. That is, it doesn't have to be sitting on the goal after the last command.
Did I catch anyone's interest? How should I approach this problem for a more efficient answer? Thanks for considering :)
Something Fun: Pastebin
It's a (very) hastily put together piece of Java. It should compile and run :) The program kinda plays ~4000 mazes at the same time. The program takes an input (w, a, s, d) for UP, LEFT, DOWN and RIGHT, and then simulates the move, showing some statistics. What you can see on the screen, should you try it, is the total amount of obstacles in every maze in each position, and the total amount of current positions of each maze. It's hard to explain :) Ask me if you have questions.
Again... don't mind the horrible code. It was written in 20 minutes..ish
Progress
I got this idea indirectly from this user's answer, and further modeled it with Mooing Duck in a chat. The idea is to find a sequence that solves the right side of the maze. That is, a solution that solves at least a half of all the mazes, and when mirrored and run again from the start solves the remaining mazes.
Illustration:
first find a sequence, whose first command is RIGHT, that solves, for example, this maze:
0 1 0 0
0 1 0 0
0 0 0 0
0 1 0 0
one such a sequence is RDDRRRD
. The mirrored counterpart of this sequence is one such that
R -> D
D -> R
L -> U
U -> L
Which means RDDRRRD
-> DRRDDDR
Now, does this mirrored sequence solve the maze? No, it gets stuck. Therefore it's not a valid sequence even for this one maze. We have to find such a sequence that it solves at least half of all the mazes, and it's mirrored counterpart solves the rest when run again from the start.
After simply brute forcing all the possible permutations of R, D and L, I got a few possible sequences.
One such sequence is RRDRRRDRLDRDR
Now the next problem is, that after running this sequence, the remaining mazes are in a random chaos. We need to get the shortest (optimal) possible sequence that will get all the remaining mazes back to the starting position (0, 0). This part I did simply by hand (for now). My answer for this is by no means optimal, but it gets all the mazes back to the beginning.
This sequence is LDLUULURUUULULL
After this we simply run the mirrored sequence, DDRDDDRDURDRD
, and we have solved all the mazes.
This particular sequence in it's entirety:
RRDRRRDRLDRDRLDLUULURUUULULLDDRDDDRDURDRD
- 41 moves
While this is a promising and awarding milestone, it's still 12 moves away from the best proved solution. Any insight is very welcome! Also, thanks to everyone who helped me so far :)
The sequence shrinks
I've been as of yet unable to programmatically get a better answer than a 58 moves long sequence. However with the method described above and just grinding the characters by hand, I've been able to shrink the sequence to be only 33 characters long. This sequence is below:
RRDRRDRLDRDLDLULLLDDRDDRDRURRRDDR
- 33 moves
While the sequence is now very close to the 29 goal, I'm still kind of looking for a programmatically aquired solution of the same caliber. There's no logic that I used when removing characters from the sequence - I just simply removed a character and checked if it solves all mazes, rinse and repeat.
Not exactly an answer but others might find it useful towards coming up with an answer.
Seems like the best approach overall is to move diagonally. However, I come across a number of tricky situations, which I list below that seem to trip up the approaches I come up with by hand.
Where:
1
is the start/end.0
is an empty spot,#
is a wall,Z
is either a wall or empty andX
is the troublesome spots, from either getting stuck or difficulty getting to them.An approach that can solve the above mazes with the smallest number of commands should be rather close to solving any maze.