I have grid N × M in which each cell is coloured with one colour.
When the player clicks on any cell of the grid of colour α, the cell in the top-leftmost corner of
Note that the cells are either their original colour, or the last selected colour.
This means that we can represent the current state of the board by means of 20 bits (marking for each of the 4*5 cells whether they contain the original colour), and a number in the range 0 to 9 giving the last colour chosen.
This results in a maximum of 10 million states to explore. The backtracking function can avoid having to recurse if it reaches a state that has already been visited. I would expect this change to make your solution considerably faster.
Representing the state by a 20bit mask and the last colour also makes the state a lot quicker to update and restore as only 2 numbers need to be changed instead of memcpy of the whole board.
If you think of the 4x5 board as "19 squares you can click on", that suggests there are 19! or 121,645,100,408,832,000 combinations to check. However, there are a number of optimisations that can drastically reduce the number of combinations to only a few dozen:
A recursive algorithm based on an optimal strategy using the rules listed above, goes through these steps for every recursion:
- If only uniquely-coloured groups are left, the number of clicks equals the number of unconnected groups; return this number.
- If a group with the same colour as the corner-group is separated from it by only one other group, click this other group and recurse. If several options exist, try all of them.
- If one or more uniquely-coloured groups (or all groups of certain colours) are adjacent to the corner group, click them all in any order. Then re-evaluate the board from step 1.
- Try clicking every colour adjacent to the corner group and recurse.
A Javascript implementation of a brute-force algorithm needed tens of millions of recursions for example 1 and 3 in the question, with an execution time far above the 8 second limit. After implementing the optimisations described above, example 1 was solved with just 38 recursions, and an execution time of a few milliseconds. Examples 2 and 3 were even quicker.