Question

I was given a brain puzzle from lonpos.cc as a present. I was curius of how many different solutions there were, and I quite enjoy writing algorithms and code, so I started writing an application to brute force it.

The puzzle looks like this : http://www.lonpos.cc/images/LONPOSdb.jpg / http://cdn100.iofferphoto.com/img/item/191/498/944/u2t6.jpg

It's a board of 20x14 "points". And all puzzle pieces can be flipped and turned. I wrote an application where each piece (and the puzzle) is presented like this:

01010
00100
01110
01110
11111
01010

Now my application so far is reasonably simple.

It takes the list of pieces and a blank board, pops of piece #0 flips it in every direction, and for that piece tries to place it for every x and y coordinate. If it successfully places a piece it passes a copy of the new "board" with some pieces taken to a recursive function, and tries all combinations for their pieces.

Explained in pseudocode:

bruteForce(Board base, List pieces) {
    for (Piece in pieces.pop, piece.pop.flip, piece.pop.flip2...) {
        int x,y = 0;
        if canplace(piece, x, y) {
            Board newBoard = base.clone();
            newBoard.placePiece(piece, x, y);
            bruteForce(newBoard, pieces);
        }
        ## increment x until x > width, then y
    }
}

Now I'm trying to find out ways to make this quicker. Things I've thought of so far:

  1. Making it solve in parallel - Implemented, now using 4 threads.
  2. Sorting the pieces, and only trying to place the pieces that will fit in the x,y space we're trying to fit. (Aka if we're on the bottom row, and we only have 4 "points" from our position to the bottom, dont try the ones that are 8 high).
  3. Not duplicating the board, instead using placePiece and removePiece or something like it.
  4. Checking for "invalid" boards, aka if a piece is impossible to reach (boxed in completely).

Anyone have any creative ideas on how I can do this quicker? Or any way to mathematically calculate how many different combinations there are?

Was it helpful?

Solution

This looks like the Exact Cover Problem. You basically want to cover all fields on the board with your given pieces. I can recommend Dancing Links, published by Donald Knuth. In the paper you find a clear example for the pentomino problem which should give you a good idea of how it works.

You basically set up a system that keeps track of all possible ways to place a specific block on the board. By placing a block, you would cover a set of positions on the field. These positions can't be used to place any other blocks. All possibilities would then be erased from the problem setting before you place another block. The dancing links allows for fast backtracking and erasing of possibilities.

OTHER TIPS

I don't see any obvious way to do things fast, but here are some tips that might help.

First off, if you ignore the bumps, you have a 6x4 grid to fill with 1x2 blocks. Each of the blocks has 6 positions where it can have a bump or a hole. Therefore, you're trying to find an arrangement of the blocks such that at each edge, a bump is matched with a hole. Also, you can represent the pieces much more efficiently using this information.

Next, I'd recommend trying all ways to place a block in a specific spot rather than all places to play a specific block anywhere. This will reduce the number of false trails you go down.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top