7

I have a 6*6 puzzle with 35 numbers(1~35) in a random sequence. Use the blank one as a 'register' and move the numbers one by one to let them be in order. I can deal with a 3*3 puzzle, but how to deal with a 6*6 one? Could you give me some hints? enter image description here

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
tmj
  • 1,143
  • 3
  • 11
  • 15

5 Answers5

7

The idea is the same, represent the problem as a states graph, and run shortest path algorithm.

If the efficiency of the algorithm is important, you might want an informed algorithm -such as A* algorithm, which is expected to be pretty fast (relative to the alternatives) with a good admissible heuristic function.
A slower though simpler solution can be running a BFS.

Both algorithms (A*, BFS) are both complete (always finds a solutuion, if one exists) and optimal (finds shortest path).

Also note, you can use macros to learn "good" series of moves, to get the algorithm faster. Ignore this improvement until you implement a working (though slow) solution.


EDIT: Coding guidelines:
Look at the problem as a graph: The graph will be G=(V,E) where V = { all possible states} and E = { (u,v) | can move from state u to state v within a single step }

Now, with this graph - you have a starting position (the source, which is given as input) and a target (a sorted puzzle). Start a BFS or A* (have a look at the pseudo code of these in the attached wikipedia links), to find a path from the source to the destination. You should start with BFS - it is simpler.
The path returned by the shortest path algorithm is identical to the series of moves you will have to do in order to get from the starting board to the target.

Note: You do not need to create the actual graph! you just need a to hold the starting node (source) - and create its vertex, and have a successors:V->2^V function, that gives you the successors for each vertex (formally: successors(v) = { (v,u) | (v,u) is in E } ). This way, you can build the relevant part of the graph on the fly.

amit
  • 175,853
  • 27
  • 231
  • 333
  • 1
    Efficiency is probably a non-issue in a matrix this small, especially if it's a homework or learning problem. – Robert Harvey Jun 20 '12 at 15:37
  • To be honest, I don't know how to solve this problem and this answer does not help. Very very high level pseudo code would be a good way to demonstrate how this would be done. – Tyler Crompton Jun 20 '12 at 15:39
  • @Tyler: This answer assumes that OP already uses this strategy for 3x3, but that it's not fast enough to work for 6x6. Without more information from OP, we can't really now what's the problem. – Niklas B. Jun 20 '12 at 15:41
  • @NiklasB.: There is no reason to use dijkstra or BF in here. A BFS will be both faster and easier to code then both - since the graph is unweighted. – amit Jun 20 '12 at 15:43
  • 3
    @NiklasB.: Since there are 36!/2 possible states and the solution could take hundreds of moves, I doubt Dijkstra or BFS will be fast enough. – interjay Jun 20 '12 at 15:45
  • @TylerCrompton: I tried to add an explanation regarding coding guidelines for this approach - do you find it more helpful? – amit Jun 20 '12 at 15:55
  • @amit, yes, I find this much more helpful with the extra links and brief explanation. – Tyler Crompton Jun 20 '12 at 16:10
  • thank you all! it helps me very much. I will study it carefully. and I didn't know this problem involves so many knowledge points. =.=_______ – tmj Jun 20 '12 at 16:14
  • @amit I used this method to solve a 15X15 square. Tried both A* and BFS, BFS was very slow and failed to complete. on the other hand,using A* the algorithm completed if the number of required steps wasn't too big, but failed (stack overflow) when the initial state was very far from the goal state. – user844541 Sep 23 '13 at 16:02
1

I've studied this same problem/puzzle when I was in college and its a very interesting problem that involves AI and heuristic techniques and graph-theory. As stated by amit, you is strongly recommended to check A*, BFS and heuristics.

Here is my contribution: when trying to solve this, you can try a divide to conquer strategy. You can think that this 6x6 grid is just four 3x3 grids coupled close each other, and try to solve each one as separated cases in a given order.

For instance, you can try the following algorithm:

  1. arrange your pieces in a manner that the left-upper grid contains all of its pieces, except one (that will be used as working space);
  2. solve the left-upper grid;
  3. arrange the right-upper grid in a manner that it contais all of its pieces, except the botttom-right one (that will be used as working space);
  4. solve the right-upper grid;
  5. ... and so on, independetly of the number of grids!

The final issue to say is that you must pay attention on which corner you gonna left as working space as you can't let the upper-right corner of the upper-right grid be your working space "missing pieces" because it will be not possible to put a piece there in future;

Ps1: working space is the position that you temporary let the piece missed, to be able to have a free space to maneuver pieces;

Ps2: in this context, grid is a combination of NxN pieces, that haves all the correct pieces, not necessarily in order.

Hope that I've helped in some way. :-)

Marcelo
  • 2,075
  • 5
  • 21
  • 38
0

A simple strategy to this game is put the right numbers on the top row (it should be easy because you don't care about other numbers, the last two numbers are a little more difficult to put in the right place because you have to place both of them in the same movement), then you freeze the top row and continue with the left column and then with the top row and then with the left column …

It is not the optimal strategy but it is one that works and is simple to code.

Thomash
  • 6,339
  • 1
  • 30
  • 50
0

I think if we will traverse the whole 6*6 Matrix At a time we will be able to find only one small number and moved it to the next Matrix which is not a relevant solution. Better way to solve this problem is use the binary search on the given matrix.If We will Apply the binary search then there will be high time complexity.So what is the better way to solve this problem

  • Requested you to all have a look in to below code.Below code is the solution for above problem.I have solved the above problem using Insertion Sort.No need to use BFS or any stuff – Prince Sanghi Apr 03 '15 at 07:07
0

I have solved the above puzzle by using Inserting Sort algorithm. It took almost 2 days for me to solve the above puzzle. Just Run below .Net code if you have to ask anything then just drop a message to me. I have not used any C# inbuilt class to solve the above problem. It's a pure c Logic Code Solution with Code

 private static void MazePuzzle()
        {
            /****
         * A typical C Problem for Maze puzzle has been solved by prince.It took almost 3 days.
         * Problem is about Sorting a 2D Matrix with any number of row and column
         * This problem is also known as Rat Maze puzzle
         * It is also be a typical Backtracking Problem
         * ***/
            const int _row = 6;
            const int _coloumn = 6;
            //int _column1 = _coloumn;

            int[,] _doubleArray = new int[_row, _coloumn] { { 19, 2, 4, 34, 23, 41 }, { 11, 63, 3, 93, 65, 98 }, { 12, 80, 15, 76, 71, 90 }, { 119, 32, 94, 84, 23, 41 }, { 129, 232, 124, 341, 253, 411 }, { 197, 289, 47, 343, 293, 401 } };
            int [] _StoringArray1D=new int[_row*_coloumn];
            int i = 0;
            int j = 0;
            int _comparingArrayElement = 0;
            int _swipeTemp = 0;


            for (; i < _row; i++)
            {
                int _trackrow = 0;
                for (;j <_coloumn; j++)
                {
                    _trackrow = 0;
                    if(i==0 && j==0)
                    {
                          _comparingArrayElement= _doubleArray[i, j + 1];
                        if(_comparingArrayElement<_doubleArray[i,j])
                        {
                             _swipeTemp = _doubleArray[i,j+1];
                             _doubleArray[i, j + 1] = _doubleArray[i, j];
                             _doubleArray[i, j] = _swipeTemp;

                        }//innerMost if
                    }//For First time
                        else
                        {
                            int k = 0;
                            do
                            {
                                if (_trackrow == i || _trackrow < i)
                                {
                                    for (; k < _coloumn; k++)
                                    {
                                        if(k==j && i==_trackrow)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                        if(_doubleArray[_trackrow,k]>_doubleArray[i,j])
                                        {
                                            int _swipetempPrevious=_doubleArray[_trackrow,k];
                                            _doubleArray[_trackrow,k]=_doubleArray[i,j];
                                            _doubleArray[i, j] = _swipetempPrevious;
                                        }
                                        else
                                        {
                                            //do nothing just traverse
                                        }//swipe else
                                        }//k==j else
                                    }//inner for do while
                                    _trackrow++;
                                    k = 0;
                                }//trackrow if
                                else
                                {
                                    break;
                                }//trackrow else
                            } while (true);
                        }//else
                }//innner for
                j = 0;
            }//outer for
            Console.WriteLine("End of Program");
        }//Maze Puzzle Method
Hans Kesting
  • 38,117
  • 9
  • 79
  • 111