I like logic exercises too much to let this one pass me by, and so I spent a while working out a solution in javascript. First the code creates a table to display results and to serve as a data structure, then there are four functions for checking horizontal, vertical and both diagonal lines. Each of those four functions has the same form: on each line, find the number of free cells with no values set, and the number of full cells containing the body. Then, if there are exactly enough free cells for the remaining cells containing the body, fill those. Finally, if there are no remaining cells containing the body, mark remaining free cells as empty.
After that, all that is left is rinse and repeat. Each time one of the four functions is run, more cells are marked as full or empty, enabling the next function to do the same with more constraints in place. Three passes from all four functions solves your sample problem, though larger and more complex shapes will certainly require more, if they can be solved at all. I can easily imagine shapes that this method would fail to solve.
function create(rows, cols) {
var table = document.createElement('table');
for (var i = 0; i < rows; i++) {
var row = table.insertRow(-1);
for (var k = 0; k < cols; k++) {
var cell = row.insertCell(-1);
cell.value = null;
cell.innerHTML = ' ';
cell.style.width = '15px';
cell.style.backgroundColor = '#cccccc';
}
}
table.maxrow = rows - 1;
table.maxcol = cols - 1;
document.body.appendChild(table);
return table;
}
function checkRows(table, rows) {
for (var i = 0; i < rows.length; i++) {
var free = 0;
var full = 0;
for (var k = 0; k <= table.maxcol; k++) {
if (table.rows[i].cells[k].value == null) {
free++;
} else if (table.rows[i].cells[k].value == 1) {
full++;
}
}
if (free == 0) {
continue;
} else if (rows[i] - full == free) {
for (var k = 0; k <= table.maxcol; k++) {
if (table.rows[i].cells[k].value == null) {
table.rows[i].cells[k].style.backgroundColor = '#ffcccc';
table.rows[i].cells[k].value = 1;
}
}
} else if (rows[i] - full == 0) {
for (var k = 0; k <= table.maxcol; k++) {
if (table.rows[i].cells[k].value == null) {
table.rows[i].cells[k].style.backgroundColor = '#ccffcc';
table.rows[i].cells[k].value = 0;
}
}
}
}
}
function checkCols(table, cols) {
for (var i = 0; i < cols.length; i++) {
var free = 0;
var full = 0;
for (var k = 0; k <= table.maxrow; k++) {
if (table.rows[k].cells[i].value == null) {
free++;
} else if (table.rows[k].cells[i].value == 1) {
full++;
}
}
if (free == 0) {
continue;
} else if (cols[i] - full == free) {
for (var k = 0; k <= table.maxrow; k++) {
if (table.rows[k].cells[i].value == null) {
table.rows[k].cells[i].style.backgroundColor = '#ffcccc';
table.rows[k].cells[i].value = 1;
}
}
} else if (cols[i] - full == 0) {
for (var k = 0; k <= table.maxrow; k++) {
if (table.rows[k].cells[i].value == null) {
table.rows[k].cells[i].style.backgroundColor = '#ccffcc';
table.rows[k].cells[i].value = 0;
}
}
}
}
}
function checkDiagonals1(table, diagonals) {
for (var i = 0; i < diagonals.length; i++) {
var row = i;
var col = 0;
if (i > table.maxrow) {
row = table.maxrow;
col = i - row;
}
var free = 0;
var full = 0;
for (var k = 0; k <= row && col + k <= table.maxcol; k++) {
if (table.rows[row - k].cells[col + k].value == null) {
free++;
} else if (table.rows[row - k].cells[col + k].value == 1) {
full++;
}
}
if (free == 0) {
continue;
} else if (diagonals[i] - full == free) {
for (var k = 0; k <= row && col + k <= table.maxcol; k++) {
if (table.rows[row - k].cells[col + k].value == null) {
table.rows[row - k].cells[col + k].style.backgroundColor = '#ffcccc';
table.rows[row - k].cells[col + k].value = 1;
}
}
} else if (diagonals[i] - full == 0) {
for (var k = 0; k <= row && col + k <= table.maxcol; k++) {
if (table.rows[row - k].cells[col + k].value == null) {
table.rows[row - k].cells[col + k].style.backgroundColor = '#ccffcc';
table.rows[row - k].cells[col + k].value = 0;
}
}
}
}
}
function checkDiagonals2(table, diagonals) {
for (var i = 0; i < diagonals.length; i++) {
var row = table.maxrow;
var col = i;
if (i > table.maxcol) {
row = table.maxrow - i + table.maxcol;
col = table.maxcol;
}
var free = 0;
var full = 0;
for (var k = 0; k <= row && k <= col; k++) {
if (table.rows[row - k].cells[col - k].value == null) {
free++;
} else if (table.rows[row - k].cells[col - k].value == 1) {
full++;
}
}
if (free == 0) {
continue;
} else if (diagonals[i] - full == free) {
for (var k = 0; k <= row && k <= col; k++) {
if (table.rows[row - k].cells[col - k].value == null) {
table.rows[row - k].cells[col - k].style.backgroundColor = '#ffcccc';
table.rows[row - k].cells[col - k].value = 1;
}
}
} else if (diagonals[i] - full == 0) {
for (var k = 0; k <= row && k <= col; k++) {
if (table.rows[row - k].cells[col - k].value == null) {
table.rows[row - k].cells[col - k].style.backgroundColor = '#ccffcc';
table.rows[row - k].cells[col - k].value = 0;
}
}
}
}
}
var rows = new Array(10, 10, 6, 4, 6, 8, 13, 15, 11, 6);
var cols = new Array(2, 4, 5, 5, 7, 6, 7, 10, 10, 10, 7, 3, 3, 5, 5);
var diagonals1 = new Array(0, 1, 2, 2, 2, 2, 4, 5, 5, 6, 7, 6, 5, 6, 6, 5, 5, 6, 6, 3, 2, 2, 1, 0);
var diagonals2 = new Array(0, 0, 1, 3, 4, 4, 4, 4, 3, 4, 5, 7, 8, 8, 9, 9, 6, 4, 4, 2, 0, 0, 0, 0);
var table = create(rows.length, cols.length);
checkRows(table, rows);
checkCols(table, cols);
checkDiagonals1(table, diagonals1);
checkDiagonals2(table, diagonals2);