I'm learning recursion but I need a reference on how to start making the algorithm. I need to organize blocks to use all the pieces, with the max possible fill of the board. Thanks to all.

- 1,394
- 1
- 15
- 26

- 513
- 3
- 9
- 26
-
@fragilewindows, I'm voting to reject your proposed edit to this question because even with your improvements, it would not meet Stack Overflow's standards. This question is asking for off site resources and should be closed. – HPierce Aug 06 '16 at 00:07
2 Answers
Recursion has two main ideas, the first is that at each step the problem (so in this case the board) you are solving the problem should get smaller. The second important idea is that each step is the same.
So in this case it would be that you place a piece and then call the function again on the board now with the placed piece removed. Lets dive into them a little bit more.
- Each time you place a piece and call the function the number of locations you can place a piece is reduced.
- Every time you call the function again, you are still just trying to place tiles. So the problem stays consistent despite the problem space being smaller.
Hope this helps!

- 891
- 1
- 13
- 31
Here is a rather naive implementation of this algorithm to help you get started.
It is looking for a perfect solution (where the board is entirely filled) and will exit as soon as it finds one. This will work as expected for your example board, but it may run forever with other boards that do not have a simple perfect solution, or no perfect solution at all.
A better algorithm would:
- Look for the best solution for any board (not just the perfect one)
- Use more heuristics to speed up the search
The only refinement in this algorithm is the use of a hash table to avoid visiting the same board twice, when two different move combinations produce the same configuration.
Each row of the board is represented as a byte and each piece is represented as 2x2 bits.
var b = [
// initial board
0b00000000,
0b00000000,
0b00000100,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
],
piece = [
// bitmasks of pieces as [ top_bitmask, bottom_bitmask ]
[ 0b11, 0b01 ], [ 0b11, 0b10 ], [ 0b01, 0b11 ], [ 0b10, 0b11 ]
],
// hash table of visited boards
hash = {},
// statistics
node = 0, hit = 0;
function solve(sol) {
var x, y, p, s;
// compute hexadecimal key representing the current board
var key =
((b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0).toString(16) + '-' +
((b[4] | (b[5] << 8) | (b[6] << 16) | (b[7] << 24)) >>> 0).toString(16);
node++;
if(hash[key]) {
// abort immediately if this board was already visited
hit++;
return false;
}
if(key == 'ffffffff-ffffffff') {
// return the current solution if the board is entirely filled
return sol;
}
// save board in hash table
hash[key] = true;
// for each position and each type of piece ...
for(y = 0; y < 7; y++) {
for(x = 0; x < 7; x++) {
for(p = 0; p < 4; p++) {
// ... see if we can insert this piece at this position
if(!(b[y] & (piece[p][0] << x)) && !(b[y + 1] & (piece[p][1] << x))) {
// make this move
b[y] ^= piece[p][0] << x;
b[y + 1] ^= piece[p][1] << x;
// add this move to the solution and process recursive call
s = solve(sol.concat(x, y, p));
// unmake this move
b[y] ^= piece[p][0] << x;
b[y + 1] ^= piece[p][1] << x;
// if we have a solution, return it
if(s) {
return s;
}
}
}
}
}
return false;
}
function display(sol) {
var n, x, y, html = '';
for(n = 0; n < 64; n++) {
html += '<div class="cell"></div>';
}
$('#container').html(html);
for(n = 0; n < sol.length; n += 3) {
for(y = 0; y < 2; y++) {
for(x = 0; x < 2; x++) {
if(piece[sol[n + 2]][y] & (1 << x)) {
$('.cell').eq(7 - sol[n] - x + (sol[n + 1] + y) * 8)
.addClass('c' + sol[n + 2]);
}
}
}
}
}
setTimeout(function() {
display(solve([]));
console.log(node + ' nodes visited');
console.log(hit + ' hash table hits');
}, 500);
#container { width:160px; height:160px }
.cell { width:19px; height:19px; margin:1px 1px 0 0; background-color:#777; float:left }
.c0 { background-color:#fb4 }
.c1 { background-color:#f8f }
.c2 { background-color:#4bf }
.c3 { background-color:#4d8 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">Searching...</div>

- 5,847
- 2
- 15
- 32