CRilliterate
Technical User
I duscovered SUDOKU
Please, try it - wonderfull mind exersize.
Enjoy and give feedback
Please, try it - wonderfull mind exersize.
Enjoy and give feedback
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 Strict//EN" "[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">[/URL]
<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml"[/URL] lang="en" xml:lang="en">
<head>
<meta name="author" content="Jeff Home" />
<meta name="description" content="Test Harness" />
<meta name="copyright" content="Copyright © 2005 - Jeff Home" />
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="content-language" content="en" />
<title>Su Doku - Test Harness</title>
<style type="text/css">
/* general styles for the page */
body {
padding:10px;
margin:10px;
font-family:Verdana,Arial,sans-serif;
}
.randomise {
width:100px;
height:40px;
border:0px;
}
table {
border-collapse:collapse;
border:3px #000000 solid;
}
td {
width:30px;
height:30px;
border:1px #999999 solid;
padding:5px;
vertical-align:middle;
text-align:center;
}
.fixed { font-style:bold; }
.bordertop { border-top:2px #666666 solid; }
.borderbottom { border-bottom:2px #666666 solid; }
.borderleft { border-left:2px #666666 solid; }
.borderright { border-right:2px #666666 solid; }
#clipboardTextarea {
padding:10px;
font-family:"Courier New",courier,sans-serif;
font-size:12px;
position:absolute;
top:100px;
left:500px;
width:230px;
height:230px;
}
</style>
<script type="text/javascript">
<!--
// preset game - 6 iterations
function game1()
{
init();
gameArray[1][2] = [6];
gameArray[2][0] = [4];
gameArray[2][1] = [7];
gameArray[3][0] = [8];
gameArray[4][1] = [6];
gameArray[5][0] = [5];
gameArray[6][0] = [6];
gameArray[6][1] = [1];
gameArray[7][2] = [2];
gameArray[1][3] = [1];
gameArray[1][4] = [2];
gameArray[1][5] = [5];
gameArray[2][4] = [6];
gameArray[3][3] = [9];
gameArray[3][5] = [2];
gameArray[4][3] = [7];
gameArray[4][5] = [4];
gameArray[5][3] = [3];
gameArray[5][5] = [6];
gameArray[6][4] = [7];
gameArray[7][3] = [6];
gameArray[7][4] = [9];
gameArray[7][5] = [8];
gameArray[1][6] = [7];
gameArray[2][7] = [5];
gameArray[2][8] = [2];
gameArray[3][8] = [7];
gameArray[4][7] = [1];
gameArray[5][8] = [8];
gameArray[6][7] = [9];
gameArray[6][8] = [5];
gameArray[7][6] = [3];
drawCanvas(true);
outputClipboard(true);
}
// preset game - 14 iterations
function game2()
{
init();
gameArray[0][0] = [7];
gameArray[0][2] = [9];
gameArray[1][0] = [2];
gameArray[1][1] = [5];
gameArray[0][5] = [2];
gameArray[1][5] = [3];
gameArray[2][5] = [1];
gameArray[2][8] = [4];
gameArray[3][0] = [9];
gameArray[4][2] = [6];
gameArray[5][1] = [3];
gameArray[5][2] = [8];
gameArray[3][3] = [7];
gameArray[5][5] = [5];
gameArray[3][6] = [6];
gameArray[3][7] = [1];
gameArray[4][6] = [8];
gameArray[5][8] = [9];
gameArray[6][0] = [6];
gameArray[6][3] = [5];
gameArray[7][3] = [8];
gameArray[8][3] = [1];
gameArray[7][7] = [4];
gameArray[7][8] = [7];
gameArray[8][6] = [9];
gameArray[8][8] = [8];
drawCanvas(true);
outputClipboard(true);
}
// preset game - 27 iterations
function game3()
{
init();
gameArray[0][0] = [3];
gameArray[0][2] = [1];
gameArray[1][0] = [2];
gameArray[0][3] = [2];
gameArray[1][4] = [4];
gameArray[1][5] = [6];
gameArray[0][6] = [5];
gameArray[1][7] = [1];
gameArray[2][6] = [9];
gameArray[3][0] = [1];
gameArray[3][1] = [7];
gameArray[4][1] = [3];
gameArray[3][5] = [5];
gameArray[5][3] = [9];
gameArray[4][7] = [7];
gameArray[5][7] = [5];
gameArray[5][8] = [1];
gameArray[6][2] = [2];
gameArray[7][1] = [9];
gameArray[8][2] = [6];
gameArray[7][3] = [8];
gameArray[7][4] = [1];
gameArray[8][5] = [9];
gameArray[7][8] = [4];
gameArray[8][6] = [1];
gameArray[8][8] = [8];
drawCanvas(true);
outputClipboard(true);
}
var gameArray = [];
var rows = cols = 9;
var iterations = 0;
var threshold = 0;
var stalled = false;
// initialise the variables and insert the clues into the gameArray
function init()
{
iterations = 0;
stalled = false;
for (var loop1 = 0; loop1 < rows; loop1++)
{
gameArray[loop1] = [];
for (var loop2 = 0; loop2 < cols; loop2++)
{
gameArray[loop1][loop2] = [];
for (var loop3 = 0; loop3 < 9; loop3++)
{
gameArray[loop1][loop2][loop3] = loop3+1;
}
}
}
drawCanvas(true);
}
// allow the user to click on a cell with 2 possible values - and choose a value to continue testing with
function clickCell()
{
var _row = parseInt((this.id).substring(1,2),10);
var _col = parseInt((this.id).substring(3,4),10);
var newData = prompt('Choose one of the two values below and continue testing',gameArray[_row][_col]);
if (newData == null) return;
if (newData == '' || isNaN(newData) || newData.length > 1 || parseInt(newData,10) == 0)
{
alert('Please type either the number '+gameArray[_row][_col][0]+' or the number ' +gameArray[_row][_col][1]);
} else {
if (parseInt(newData,10) == gameArray[_row][_col][0] || parseInt(newData,10) == gameArray[_row][_col][1])
{
gameArray[_row][_col] = [parseInt(newData,10)];
check(threshold);
} else {
alert('Please type either the number '+gameArray[_row][_col][0]+' or the number ' +gameArray[_row][_col][1]);
}
}
}
// allow the user to click on a cell and edit it's contents at the initial data entry phase
function dataEntry()
{
var _row = parseInt((this.id).substring(1,2),10);
var _col = parseInt((this.id).substring(3,4),10);
var newData = prompt('Enter a number for this cell','1-9 only');
if (newData == null) return;
if (newData == '' || isNaN(newData) || newData.length > 1 || parseInt(newData,10) == 0)
{
if (newData == '' || parseInt(newData,10) == 0) gameArray[_row][_col] = [1,2,3,4,5,6,7,8,9];
} else {
gameArray[_row][_col] = [parseInt(newData,10)];
}
drawCanvas(true);
}
// write the contents of the gameArray to the page
function drawCanvas(_dataload)
{
for (var loop1 = 0; loop1 < rows; loop1++)
{
for (var loop2 = 0; loop2 < cols; loop2++)
{
if (typeof(_dataload) != 'undefined')
{
document.getElementById('r'+loop1+'c'+loop2).onclick = dataEntry;
} else {
document.getElementById('r'+loop1+'c'+loop2).onclick = null;
}
document.getElementById('r'+loop1+'c'+loop2).onclick = dataEntry;
document.getElementById('r'+loop1+'c'+loop2).title = gameArray[loop1][loop2];
document.getElementById('r'+loop1+'c'+loop2).innerHTML = '?';
document.getElementById('r'+loop1+'c'+loop2).style.fontWeight = 'normal';
if (gameArray[loop1][loop2].length == 2)
{
document.getElementById('r'+loop1+'c'+loop2).onclick = clickCell;
document.getElementById('r'+loop1+'c'+loop2).style.backgroundColor = '#aaddee';
document.getElementById('r'+loop1+'c'+loop2).innerHTML = gameArray[loop1][loop2];
} else {
if (gameArray[loop1][loop2].length == 1)
{
document.getElementById('r'+loop1+'c'+loop2).style.fontWeight = 'bold';
document.getElementById('r'+loop1+'c'+loop2).style.backgroundColor = '#eeeeee';
document.getElementById('r'+loop1+'c'+loop2).innerHTML = gameArray[loop1][loop2];
} else {
document.getElementById('r'+loop1+'c'+loop2).style.backgroundColor = '#ffffff';
}
}
}
}
}
// output the solved game to a text format for emailing
function outputClipboard(_export)
{
var myExport = _export;
var myClipboard = ' Total iterations: ' + iterations + '<br /><br />';
if (myExport==true) myClipboard = ' Current game board...<br /><br />';
for (var loop = 0; loop < rows; loop++)
{
for (var loop2 = 0; loop2 < cols; loop2++)
{
myClipboard += ' ';
if (myExport == true)
{
if (gameArray[loop][loop2].length == 1)
myClipboard += gameArray[loop][loop2];
else
myClipboard += '.';
} else {
myClipboard += gameArray[loop][loop2];
}
if (loop2%3==2 && loop2!=8) myClipboard += ' |';
}
myClipboard += '<br />';
if (loop%3==2 && loop!=8) myClipboard += ' ------+-------+------ <br />';
}
document.getElementById('clipboardTextarea').value = myClipboard.replace(/<br \/>/g,'\n') + '\n';
}
// begin the process of solving the problem
function check(_threshold)
{
if (typeof(_threshold) != undefined) threshold = _threshold;
iterations++;
var startArray = gameArray.concat();
// check rows
for (var loop = 0; loop < rows; loop++)
{
gameArray[loop] = checkRow(loop);
}
// check columns
for (var loop = 0; loop < cols; loop++)
{
var myCol = checkCol(loop);
for (var loop2 = 0; loop2 < rows; loop2++)
{
gameArray[loop2][loop] = myCol[loop2];
}
}
// check blocks
for (var loop = 0; loop < cols; loop++)
{
var myBlock = checkBlock(loop);
gameArray[Math.floor(loop/3)*3][(loop%3)*3] = myBlock[0];
gameArray[Math.floor(loop/3)*3][(loop%3)*3+1] = myBlock[1];
gameArray[Math.floor(loop/3)*3][(loop%3)*3+2] = myBlock[2];
gameArray[Math.floor(loop/3)*3+1][(loop%3)*3] = myBlock[3];
gameArray[Math.floor(loop/3)*3+1][(loop%3)*3+1] = myBlock[4];
gameArray[Math.floor(loop/3)*3+1][(loop%3)*3+2] = myBlock[5];
gameArray[Math.floor(loop/3)*3+2][(loop%3)*3] = myBlock[6];
gameArray[Math.floor(loop/3)*3+2][(loop%3)*3+1] = myBlock[7];
gameArray[Math.floor(loop/3)*3+2][(loop%3)*3+2] = myBlock[8];
}
if (startArray.toString() == gameArray.toString() && gameArray.toString().length == rows*cols*2-1 && gameArray.toString().indexOf(',,') < 0)
{
// puzzle solved
drawCanvas();
outputClipboard(false);
} else {
if (startArray.toString() == gameArray.toString())
{
drawCanvas();
if (stalled) {
alert('We have stalled after '+iterations+' iterations!');
} else {
stalled = true;
checkRowAndColumnNumbers();
check(threshold);
}
} else {
stalled = false;
if (iterations < threshold)
{
check(threshold);
} else {
drawCanvas();
}
}
}
}
// return the intersection of values in _arr2 and _arr1
function reduceArray(_arr1,_arr2)
{
var _tempArr = [];
for (var loop = 0; loop < _arr2.length; loop++)
{
if (_arr1.toString().indexOf(_arr2[loop]) > -1) _tempArr[_tempArr.length] = _arr2[loop];
}
return _tempArr;
}
// scan a row and return an array of possible values
function checkRow(_rowNum)
{
var myRow = gameArray[_rowNum];
var mySoln = [];
var myPoss = [];
for (var loop = 0; loop < cols; loop++)
{
if (myRow[loop].length == 1)
{
mySoln[mySoln.length] = [myRow[loop][0]];
} else {
mySoln[mySoln.length] = 0;
}
}
for (var loop = 1; loop <= 9; loop++)
{
if (mySoln.toString().indexOf(loop) < 0)
{
myPoss[myPoss.length] = loop;
}
}
var tempArray = mySoln.concat();
for (var loop = 0; loop < cols; loop++)
{
if (mySoln[loop] == 0)
{
tempArray[loop] = reduceArray(myPoss,myRow[loop]);
if (tempArray[loop].length == 1) mySoln[loop] = tempArray[loop];
}
}
return tempArray;
}
// scan each row and column and try to find a unique number that can be placed
function checkRowAndColumnNumbers()
{
// check the rows
for (var _rowNum = 0; _rowNum < rows; _rowNum++)
{
var myRow = gameArray[_rowNum];
var mySoln = [];
for (var loop = 0; loop < cols; loop++)
{
if (myRow[loop].length == 1)
{
mySoln[mySoln.length] = [myRow[loop][0]];
}
}
for (var loop = 1; loop <= 9; loop++)
{
if (mySoln.toString().indexOf(loop) < 0 && myRow.toString().indexOf(loop) == myRow.toString().lastIndexOf(loop) && myRow.toString().indexOf(loop) > -1)
{
for (var loop2 = 0; loop2 < cols; loop2++)
{
if (myRow[loop2].toString().indexOf(loop) >= 0) gameArray[_rowNum][loop2] = [loop];
}
}
}
}
// check the columns
for (var _colNum = 0; _colNum < cols; _colNum++)
{
var myCol = [];
for (var loop = 0; loop < rows; loop++) myCol[myCol.length] = gameArray[loop][_colNum];
var mySoln = [];
for (var loop = 0; loop < rows; loop++)
{
if (myCol[loop].length == 1)
{
mySoln[mySoln.length] = [myCol[loop][0]];
}
}
for (var loop = 1; loop <= 9; loop++)
{
if (mySoln.toString().indexOf(loop) < 0 && myCol.toString().indexOf(loop) == myCol.toString().lastIndexOf(loop) && myCol.toString().indexOf(loop) > -1)
{
for (var loop2 = 0; loop2 < rows; loop2++)
{
if (myCol[loop2].toString().indexOf(loop) >= 0) gameArray[loop2][_colNum] = [loop];
}
}
}
}
// drawCanvas();
}
// scan a column and return an array of possible values
function checkCol(_colNum)
{
var myCol = [];
for (var loop = 0; loop < rows; loop++) myCol[myCol.length] = gameArray[loop][_colNum];
var mySoln = [];
var myPoss = [];
for (var loop = 0; loop < rows; loop++)
{
if (myCol[loop].length == 1)
{
mySoln[mySoln.length] = [myCol[loop][0]];
} else {
mySoln[mySoln.length] = 0;
}
}
for (var loop = 1; loop <= 9; loop++)
{
if (mySoln.toString().indexOf(loop) < 0)
{
myPoss[myPoss.length] = loop;
}
}
var tempArray = mySoln.concat();
for (var loop = 0; loop < cols; loop++)
{
if (mySoln[loop] == 0)
{
tempArray[loop] = reduceArray(myPoss,myCol[loop]);
if (tempArray[loop].length == 1) mySoln[loop] = tempArray[loop];
}
}
return tempArray;
}
// scan a block of 9 and return an array of possible values
function checkBlock(_blockNum)
{
_col = _blockNum%3;
_row = Math.floor(_blockNum/3);
var myBlock = [];
myBlock[0] = gameArray[_row*3][_col*3];
myBlock[1] = gameArray[_row*3][_col*3+1];
myBlock[2] = gameArray[_row*3][_col*3+2];
myBlock[3] = gameArray[_row*3+1][_col*3];
myBlock[4] = gameArray[_row*3+1][_col*3+1];
myBlock[5] = gameArray[_row*3+1][_col*3+2];
myBlock[6] = gameArray[_row*3+2][_col*3];
myBlock[7] = gameArray[_row*3+2][_col*3+1];
myBlock[8] = gameArray[_row*3+2][_col*3+2];
var mySoln = [];
var myPoss = [];
for (var loop = 0; loop < myBlock.length; loop++)
{
if (myBlock[loop].length == 1)
{
mySoln[mySoln.length] = [myBlock[loop][0]];
} else {
mySoln[mySoln.length] = 0;
}
}
for (var loop = 1; loop <= 9; loop++)
{
if (mySoln.toString().indexOf(loop) < 0)
{
myPoss[myPoss.length] = loop;
}
}
var tempArray = mySoln.concat();
for (var loop = 0; loop < cols; loop++)
{
if (mySoln[loop] == 0)
{
tempArray[loop] = reduceArray(myPoss,myBlock[loop]);
if (tempArray[loop].length == 1) mySoln[loop] = tempArray[loop];
}
}
return tempArray;
}
//-->
</script>
</head>
<body onload="init()">
<a href="javascript:check(100)">Find the solution</a> || <a href="javascript:check(1)">Step forward</a> || <a href="javascript:init()">Clear Board</a> || <a href="javascript:outputClipboard(true)">Export Board</a><br /><br />
<a href="javascript:game1()">Load Easy Game</a> || <a href="javascript:game2()">Load Difficult Game</a> || <a href="javascript:game3()">Load Fiendish Game</a><br /><br />
<table>
<tr><td id="r0c0" class="bordertop borderleft"></td>
<td id="r0c1" class="bordertop"></td>
<td id="r0c2" class="bordertop"></td>
<td id="r0c3" class="bordertop borderleft"></td>
<td id="r0c4" class="bordertop"></td>
<td id="r0c5" class="bordertop"></td>
<td id="r0c6" class="bordertop borderleft"></td>
<td id="r0c7" class="bordertop"></td>
<td id="r0c8" class="bordertop borderright"></td>
</tr>
<tr><td id="r1c0" class="borderleft"></td>
<td id="r1c1"></td>
<td id="r1c2"></td>
<td id="r1c3" class="borderleft"></td>
<td id="r1c4"></td>
<td id="r1c5"></td>
<td id="r1c6" class="borderleft"></td>
<td id="r1c7"></td>
<td id="r1c8" class="borderright"></td>
</tr>
<tr><td id="r2c0" class="borderleft borderbottom"></td>
<td id="r2c1" class="borderbottom"></td>
<td id="r2c2" class="borderbottom"></td>
<td id="r2c3" class="borderbottom borderleft"></td>
<td id="r2c4" class="borderbottom"></td>
<td id="r2c5" class="borderbottom"></td>
<td id="r2c6" class="borderbottom borderleft"></td>
<td id="r2c7" class="borderbottom"></td>
<td id="r2c8" class="borderright borderbottom"></td>
</tr>
<tr><td id="r3c0" class="borderleft"></td>
<td id="r3c1"></td>
<td id="r3c2"></td>
<td id="r3c3" class="borderleft"></td>
<td id="r3c4"></td>
<td id="r3c5"></td>
<td id="r3c6" class="borderleft"></td>
<td id="r3c7"></td>
<td id="r3c8" class="borderright"></td>
</tr>
<tr><td id="r4c0" class="borderleft"></td>
<td id="r4c1"></td>
<td id="r4c2"></td>
<td id="r4c3" class="borderleft"></td>
<td id="r4c4"></td>
<td id="r4c5"></td>
<td id="r4c6" class="borderleft"></td>
<td id="r4c7"></td>
<td id="r4c8" class="borderright"></td>
</tr>
<tr><td id="r5c0" class="borderleft borderbottom"></td>
<td id="r5c1" class="borderbottom"></td>
<td id="r5c2" class="borderbottom"></td>
<td id="r5c3" class="borderbottom borderleft"></td>
<td id="r5c4" class="borderbottom"></td>
<td id="r5c5" class="borderbottom"></td>
<td id="r5c6" class="borderbottom borderleft"></td>
<td id="r5c7" class="borderbottom"></td>
<td id="r5c8" class="borderright borderbottom"></td>
</tr>
<tr><td id="r6c0" class="borderleft"></td>
<td id="r6c1"></td>
<td id="r6c2"></td>
<td id="r6c3" class="borderleft"></td>
<td id="r6c4"></td>
<td id="r6c5"></td>
<td id="r6c6" class="borderleft"></td>
<td id="r6c7"></td>
<td id="r6c8" class="borderright"></td>
</tr>
<tr><td id="r7c0" class="borderleft"></td>
<td id="r7c1"></td>
<td id="r7c2"></td>
<td id="r7c3" class="borderleft"></td>
<td id="r7c4"></td>
<td id="r7c5"></td>
<td id="r7c6" class="borderleft"></td>
<td id="r7c7"></td>
<td id="r7c8" class="borderright"></td>
</tr>
<tr><td id="r8c0" class="borderleft borderbottom"></td>
<td id="r8c1" class="borderbottom"></td>
<td id="r8c2" class="borderbottom"></td>
<td id="r8c3" class="borderbottom borderleft"></td>
<td id="r8c4" class="borderbottom"></td>
<td id="r8c5" class="borderbottom"></td>
<td id="r8c6" class="borderbottom borderleft"></td>
<td id="r8c7" class="borderbottom"></td>
<td id="r8c8" class="borderright borderbottom"></td>
</tr>
</table>
<div id="clipboardDiv"></div>
<textarea id="clipboardTextarea"></textarea>
</body>
</html>