var x = 3;
var y = 3;
function cross(A, B) {
//Cross product of elements in A and elements in B.
var arr = [];
var alen = A.length;
var blen = B.length;
for (var i = 0; i < alen; i++) {
for (var ii = 0; ii < blen; ii++) {
arr.push(A[i] + "-" + B[ii])
}
}
return arr
}
var digits = [];
var rows = [];
var cols = [];
var squares;
var unitlist = [];
var subrows = [];
var subcols = [];
var units = {};
var peers = {};
function fillable_puzzle() {
digits = [];
rows = [];
cols = [];
for (var i = 1; i < x * y + 1; i++) {
rows.push(i);
cols.push(i);
digits.push(i);
}
squares = cross(rows, cols)
unitlist = [];
subrows = [];
subcols = [];
for (var c in cols) {
unitlist.push(cross(rows, [cols[c]]));
}
for (var r in rows) {
unitlist.push(cross([rows[r]], cols));
}
for (var i = 0; i < y; i++) {
var A = [];
for (var ii = 0; ii < x; ii++) {
A.push(i * x + ii + 1);
}
for (var ii = 0; ii < x; ii++) {
var B = [];
for (var iii = 0; iii < y; iii++) {
B.push(ii * y + iii + 1);
subcols.push(cross(A, [ii * y + iii + 1]));
}
unitlist.push(cross(A, B));
}
}
for (var ii = 0; ii < x; ii++) {
var B = [];
for (var iii = 0; iii < y; iii++) {
B.push(ii * y + iii + 1);
}
for (var i = 0; i < y; i++) {
for (var iii = 0; iii < x; iii++) {
subrows.push(cross([i * x + iii + 1], B));
}
}
}
units = {};
peers = {};
for (var i in squares) {
var s = squares[i];
units[s] = [];
peers[s] = {};
for (var ii in unitlist) {
var u = unitlist[ii];
for (var iii in u) {
var uu = u[iii];
if (s == uu) {
units[s].push(u);
for (var iiii in u) {
if (u[iiii] != s) {
peers[s][u[iiii]] = true;
}
}
break;
}
}
}
}
var fills = {};
for (var i in squares) {
var s = squares[i];
fills[s] = 0;
}
return fills
}
function fitSpotBasic(fills, s, v) {
for (var u in units[s]) {
for (var i in units[s][u]) {
var ss = units[s][u][i];
if (fills[ss] == v) {
return false;
}
}
}
return true;
}
function allDigitsBasic(fills, s) {
var dposs = [];
if (fills[s] != 0) { dposs = [fills[s]]; return dposs; }
for (var vi in digits) {
var v = digits[vi];
if (fitSpotBasic(fills, s, v)) {
dposs.push(v);
}
}
return dposs;
}
function findNakedPairs(fills) {
var nps = {};
for (var ui in unitlist) {
var unit = unitlist[ui];
var pairs = [];
for (var i in unit) {
var ss = unit[i];
if (fills[ss] != 0) {
continue;
}
var dposs = allDigitsBasic(fills, ss);
if (dposs.length == 2) {
dposs.sort();
var str = dposs.join(";");
pairs.push([str, ss]);
}
}
if (pairs.length > 1) {
for (var i = 0; i < pairs.length; i++) {
for (var ii = i + 1; ii < pairs.length; ii++) {
if (pairs[i][0] == pairs[ii][0]) {
var dposs = pairs[i][0].split(";");
for (var iii in unit) {
var ss = unit[iii];
if (ss != pairs[i][1] && ss != pairs[ii][1]) {
if (!nps[ss]) { nps[ss] = {}; }
nps[ss][dposs[0]] = true;
nps[ss][dposs[1]] = true;
}
}
}
}
}
}
}
return nps;
}
function fitSpotNakedPair(fills, s, v, nps) {
if (nps[s] && nps[s][v]) {
return false;
}
for (var u in units[s]) {
for (var i in units[s][u]) {
var ss = units[s][u][i];
if (fills[ss] == v) {
return false;
}
}
}
return true;
}
function findHiddenPairs(fills) {
var hps = {};
for (var ui in unitlist) {
var unit = unitlist[ui];
var sposs = {};
for (var i in unit) {
var ss = unit[i];
if (fills[ss] != 0) {
continue;
}
var dposs = allDigitsBasic(fills, ss);
for (var di = 0; di < dposs.length; di++) {
if (!sposs[dposs[di]]) { sposs[dposs[di]] = []; }
sposs[dposs[di]].push(ss);
}
}
var pairs = [];
for (var si in sposs) {
if (sposs[si].length == 2) {
sposs[si].sort();
pairs.push([sposs[si].join(";"), si]);
}
}
if (pairs.length > 1) {
for (var i = 0; i < pairs.length; i++) {
for (var ii = i + 1; ii < pairs.length; ii++) {
if (pairs[i][0] == pairs[ii][0]) {
var sposs = pairs[i][0].split(";");
if (!hps[sposs[0]]) { hps[sposs[0]] = {}; }
if (!hps[sposs[1]]) { hps[sposs[1]] = {}; }
for (var iii in digits) {
var v = digits[iii];
if (v != pairs[i][1] && v != pairs[ii][1]) {
hps[sposs[1]][v] = true;
hps[sposs[0]][v] = true;
}
}
}
}
}
}
}
return hps;
}
function findDefiniteSubunitInBlock(fills, unitt) {
var nps = {};
var subs;
if (unitt == 1) {
subs = subrows;
}
else {
subs = subcols;
}
for (var vi in digits) {
var v = digits[vi];
var pblocks = {};
for (var ui in subs) {
var subunit = subs[ui];
var count = 0;
for (var i in subunit) {
if (fills[subunit[i]] == 0) {
if (fitSpotBasic(fills, subunit[i], v)) {
count++;
}
}
}
if (count > 0) {
var block = units[subunit[0]][2][0];
if (pblocks[block]) {
pblocks[block].push(ui);
pblocks[block].push(count);
}
else {
pblocks[block] = [ui, count];
}
}
}
for (var bi in pblocks) {
if (pblocks[bi].length == 2) {
if (pblocks[bi][1] > 1) {
var row = units[subs[pblocks[bi][0]][0]][unitt];
for (var ri in row) {
var block = units[row[ri]][2][0];
if (block != bi) {
if (fills[row[ri]] == 0 && fitSpotBasic(fills, row[ri], v)) {
if (!nps[row[ri]]) { nps[row[ri]] = {}; }
nps[row[ri]][v] = true;
}
}
}
}
}
}
}
return nps;
}
function findDefiniteSubunitInUnit(fills, unitt) {
var nps = {};
var subs;
if (unitt == 1) {
subs = subrows;
}
else {
subs = subcols;
}
for (var vi in digits) {
var v = digits[vi];
var prows = {};
for (var ui in subs) {
var subunit = subs[ui];
var count = 0;
for (var i in subunit) {
if (fills[subunit[i]] == 0) {
if (fitSpotBasic(fills, subunit[i], v)) {
count++;
}
}
}
if (count > 0) {
var row = units[subunit[0]][unitt][0];
if (prows[row]) {
prows[row].push(ui);
prows[row].push(count);
}
else {
prows[row] = [ui, count];
}
}
}
for (var ri in prows) {
if (prows[ri].length == 2) {
if (prows[ri][1] > 1) {
var block = units[subs[prows[ri][0]][0]][2];
for (var bi in block) {
var row = units[block[bi]][unitt][0];
if (row != ri) {
if (fills[block[bi]] == 0 && fitSpotBasic(fills, block[bi], v)) {
if (!nps[block[bi]]) { nps[block[bi]] = {}; }
nps[block[bi]][v] = true;
}
}
}
}
}
}
}
return nps;
}
function finishUnit(fills) {
var possiblePlays = [];
for (var ui in unitlist) {
var unit = unitlist[ui];
var count = 0;
var cell = -1;
var current = {};
for (var i in unit) {
if (fills[unit[i]] == 0) {
count++;
cell = unit[i];
}
else {
current[fills[unit[i]]] = true;
}
}
if (count == 1) {
for (var i in digits) {
if (!current[digits[i]]) {
if (ui < unitlist.length / 3) {
possiblePlays.push([cell, digits[i], 1]);
}
else if (ui < unitlist.length * 2 / 3) {
possiblePlays.push([cell, digits[i], 2]);
}
else if (ui < unitlist.length) {
possiblePlays.push([cell, digits[i], 3]);
}
break;
}
}
}
}
return possiblePlays;
}
function oneSpotInUnit(fills, nps = false, level = 2) {
var possiblePlays = [];
for (var ui in unitlist) {
var unit = unitlist[ui];
for (var vi in digits) {
var v = digits[vi];
var count = 0;
var cell = -1;
for (var i in unit) {
if (fills[unit[i]] == 0) {
if (nps) {
if (fitSpotNakedPair(fills, unit[i], v, nps)) {
count++;
cell = unit[i];
}
}
else {
if (fitSpotBasic(fills, unit[i], v)) {
count++;
cell = unit[i];
}
}
}
else if (fills[unit[i]] == v) {
//value already in unit
count = 0;
break;
}
}
if (count == 1) {
if (nps) {
if (ui < unitlist.length / 3) {
possiblePlays.push([cell, v, level, 4]);
}
else if (ui < unitlist.length * 2 / 3) {
possiblePlays.push([cell, v, level, 5]);
}
else if (ui < unitlist.length) {
possiblePlays.push([cell, v, level, 6]);
}
}
else {
if (ui < unitlist.length / 3) {
possiblePlays.push([cell, v, 4]);
}
else if (ui < unitlist.length * 2 / 3) {
possiblePlays.push([cell, v, 5]);
}
else if (ui < unitlist.length) {
possiblePlays.push([cell, v, 6]);
}
}
}
}
}
return possiblePlays;
}
function oneDigitInSpot(fills, nps = false, level = 2) {
var possiblePlays = [];
for (var si in squares) {
var s = squares[si];
if (fills[s] != 0) { continue; }
var count = 0;
var out = -1;
for (var vi in digits) {
var v = digits[vi];
if (nps) {
if (fitSpotNakedPair(fills, s, v, nps)) {
count++;
if (count > 1) {
break;
}
out = v;
}
}
else {
if (fitSpotBasic(fills, s, v)) {
count++;
if (count > 1) {
break;
}
out = v;
}
}
}
if (count == 1) {
if (nps) {
possiblePlays.push([s, out, level]);
}
else {
possiblePlays.push([s, out, 7]);
}
}
}
return possiblePlays;
}
function removeEmpties(possiblePlays, fills) {
for (var i = possiblePlays.length - 1; i >= 0; i--) {
if (fills[possiblePlays[i][0]] != 0) {
possiblePlays.splice(i, 1);
}
}
return possiblePlays;
}
function simpleSolve(fills, all = false) {
var possiblePlays = [];
possiblePlays = possiblePlays.concat(finishUnit(fills));
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills));
//if (possiblePlays.length > 0 && !all){return possiblePlays;}
possiblePlays = removeEmpties(possiblePlays, fills);
if (possiblePlays.length > 0 && !all) {
return possiblePlays;
}
var fps = {};
var dps = findDefiniteSubunitInBlock(fills, 1);
if (Object.keys(dps).length > 0) {
for (var d in dps) {
if (!fps[d]) { fps[d] = {}; }
for (var dd in dps[d]) {
fps[d][dd] = true;
}
}
//console.log(dps);
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills, dps, 8));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills, dps, 9));
}
var dps = findDefiniteSubunitInBlock(fills, 0);
if (Object.keys(dps).length > 0) {
for (var d in dps) {
if (!fps[d]) { fps[d] = {}; }
for (var dd in dps[d]) {
fps[d][dd] = true;
}
}
//console.log(dps);
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills, dps, 10));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills, dps, 11));
}
//if (possiblePlays.length > 0 && !all){return possiblePlays;}
var dps = findDefiniteSubunitInUnit(fills, 1);
if (Object.keys(dps).length > 0) {
for (var d in dps) {
if (!fps[d]) { fps[d] = {}; }
for (var dd in dps[d]) {
fps[d][dd] = true;
}
}
//console.log(dps);
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills, dps, 12));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills, dps, 13));
}
//if (possiblePlays.length > 0 && !all){return possiblePlays;}
//if (possiblePlays.length > 0 && !all){return possiblePlays;}
var dps = findDefiniteSubunitInUnit(fills, 0);
if (Object.keys(dps).length > 0) {
for (var d in dps) {
if (!fps[d]) { fps[d] = {}; }
for (var dd in dps[d]) {
fps[d][dd] = true;
}
}
//console.log(dps);
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills, dps, 14));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills, dps, 15));
}
//if (possiblePlays.length > 0 && !all){return possiblePlays;}
/*
if (Object.keys(fps).length > 0){
//console.log(dps);
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills,fps,4));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills,fps,4));
}
*/
var nps = findNakedPairs(fills);
if (Object.keys(nps).length > 0) {
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills, nps, 16));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills, nps, 17));
}
//if (possiblePlays.length > 0 && !all){return possiblePlays;}
var hps = findHiddenPairs(fills);
if (Object.keys(hps).length > 0) {
//console.log(hps);
possiblePlays = possiblePlays.concat(oneSpotInUnit(fills, hps, 18));
possiblePlays = possiblePlays.concat(oneDigitInSpot(fills, hps, 19));
}
possiblePlays = removeEmpties(possiblePlays, fills);
return possiblePlays;
}
var x = 3;
var y = 3;
function cross(A, B){
//Cross product of elements in A and elements in B.
var arr = [];
var alen = A.length;
var blen = B.length;
for (var i=0;i<alen;i++){
for (var ii=0;ii<blen;ii++){
arr.push(A[i]+"-"+B[ii])
}
}
return arr
}
var digits = [];
var rows = [];
var cols = [];
var squares;
var unitlist = [];
var rowlist = [];
var collist = [];
var blocklist = [];
var units = {};
var peers = {};
function reset_puzzle(){
digits = [];
rows = [];
cols = [];
for (var i=1;i<x*y+1;i++){
rows.push(i);
cols.push(i);
digits.push(i);
}
squares = cross(rows, cols)
unitlist = [];
rowlist = [];
collist = [];
blocklist = [];
for (var c in cols){
unitlist.push(cross(rows,[cols[c]]));
collist.push(cross(rows,[cols[c]]));
}
for (var r in rows){
unitlist.push(cross([rows[r]],cols));
rowlist.push(cross([rows[r]],cols));
}
for (var i=0;i<y;i++){
var A = [];
for (var ii=0;ii<x;ii++){
A.push(i*x+ii+1);
}
for (var ii=0;ii<x;ii++){
var B = [];
for (var iii=0;iii<y;iii++){
B.push(ii*y+iii+1);
}
unitlist.push(cross(A,B));
blocklist.push(cross(A,B));
}
}
units = {};
peers = {};
for (var i in squares){
var s = squares[i];
units[s]=[];
peers[s]={};
for (var ii in unitlist){
var u = unitlist[ii];
for (var iii in u){
var uu = u[iii];
if (s == uu){
units[s].push(u);
for (var iiii in u){
if (u[iiii] != s){
peers[s][u[iiii]]=true;
}
}
break;
}
}
}
}
//console.log(squares);
//console.log(units);
//console.log(peers);
}
function create_grid(){
//To start, every square can be any digit;
reset_puzzle();
var values = {};
for (var i in squares){
var s = squares[i];
values[s]=digits;
}
return values
}
function assign(values, s, d){
//Eliminate all the other values (except d) from values[s] and propagate.
//Return values, except return False if a contradiction is detected.
var other_values = values[s].slice()
for (var i in other_values){
if (other_values[i] != d){
var elim = eliminate(values, s, other_values[i]);
if (!elim){return false;}
else {values = elim;}
}
}
return values;
}
function eliminate(values, s, d){
//Eliminate d from values[s]; propagate when values or places <= 2.
//Return values, except return False if a contradiction is detected.
var skipped = false;
var new_vals = values[s].slice();
for (var i=0;i<new_vals.length;i++){
if (new_vals[i] == d){
new_vals.splice(i,1);
skipped = true;
break;
}
}
if (!skipped){
return values //Already eliminated
}
values[s] = new_vals;
//If a square s is reduced to one value d2, then eliminate d2 from the peers.
if (values[s].length == 0){
return false //Contradiction: removed last value
}
else if (values[s].length == 1){
var d2 = values[s][0]
var my_peers = peers[s];
for (var i in my_peers){
var s2 = i;
var elim = eliminate(values, s2, d2);
if (!elim){
return false;
}
else {
values = elim;
}
}
}
//If a unit u is reduced to only one place for a value d, then put it there.
for (var i in units[s]){
var u = units[s][i];
var dplaces = 0;
var sz1 = u.length;
for (var ii=0;ii<sz1;ii++){
var s = u[ii];
var sz2 = values[s].length;
for (var iii=0;iii<sz2;iii++){
if (d == values[s][iii]){
if (dplaces != 0){
dplaces = -1;
ii=sz1+5;
}
else {
dplaces = s;
}
break;
}
else if (d < values[s][iii]) {
break;
}
}
}
if (dplaces == 0){
return false //Contradiction: no place for this value
}
else if (dplaces != -1){
//d can only be in one place in unit; assign it there
var a = assign(values, dplaces, d);
if (!a){
return false
}
else {
values = a;
}
}
}
return values
}
function random_puzzle(xx=3,yy=3){
//Make a random puzzle with N or more assignments. Restart on contradictions.
x = xx;
y = yy;
var values = create_grid();
var totalT = 0;
var misses = 0;
for (var i=0;i<x*y;i++){
var s = squares[i];
var v = digits[i];
values[s]=[v];
}
for (var i=x*y;i<x*y*x;i++){
var s = squares[i];
var minV = Math.floor((i%(x*y))/y);
minV *= y;
var maxV = minV + y;
var arr = [];
var idx = 0;
for (var ii=0;ii<x*y;ii++){
if (ii < minV || ii >= maxV){
arr[idx]=digits[ii];
idx++;
}
}
values[s] = arr;
}
for (var i=x*y*x;i<x*y*x*y;i++){
var s = squares[i];
var minV = i%(x*y);
var maxV = minV + 1;
var arr = [];
var idx = 0;
for (var ii=0;ii<x*y;ii++){
if (ii < minV || ii >= maxV){
arr[idx]=digits[ii];
idx++;
}
}
values[s] = arr;
}
var valuesOld = [];
var t1 = Date.now();
for (var i=0;i<x*y*x*y*200;i++){
var minOptions = x*y*2;
var sqs = [];
for (var ii in squares){
var ss = squares[ii];
if (values[ss].length > 1){
if (values[ss].length < minOptions){
minOptions = values[ss].length;
sqs = [ss];
}
else if (values[ss].length == minOptions){
sqs.push(ss);
}
}
}
if (minOptions == x*y*2){
break;
}
var s = sqs[Math.floor(Math.random()*sqs.length)];
var v = values[s][Math.floor(Math.random()*values[s].length)];
var vvOld = {};
for (var vv in values){
vvOld[vv]=values[vv].slice();
}
valuesOld.push(vvOld);
if (valuesOld.length >= 5){
valuesOld.splice(0,1);
}
values = assign(values, s, v);
if (!values){
misses++;
if (misses > 10){
break;
}
values = {};
for (var vv in valuesOld[0]){
values[vv]=valuesOld[0][vv].slice();
}
continue;
}
}
var t2 = Date.now();
totalT += t2-t1;
var pout = [];
for (var i=0;i<x*y;i++){
for (var ii=0;ii<x*y;ii++){
var s = squares[i*x*y+ii];
if (!values[s] || values[s].length != 1){return false;}
var v = values[s][0];
pout.push(v);
}
}
return pout;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="favicon.png">
<title></title>
<meta name="description" content="" />
<link href="style.css" rel="stylesheet" type="text/css" />
<style>
#container {
display: none;
position: relative;
top:0;
}
#container2 {
display: block;
position: relative;
left:calc(16 * 2rem);
left: 0;
}
@media (orientation: portrait) {
#container2 {
top:calc(16 * 2rem);
top: 0;
left: 0;
}
}
.cell {
border: 1px solid black;
display: inline-block;
height: 2rem;
width: 2rem;
position: absolute;
line-height: 2rem;
text-align: center;
cursor: pointer;
}
{% for i in range(1,17) %}
.row-{{i}} {
top: calc(2rem * {{i}});
}
.col-{{i}} {
left: calc(2rem * {{i}});
}
{% endfor %}
</style>
</head>
<body>
<div id="menu">
x: <input type="number" min="2" max="5" value="3" onchange="updatePuzzle()" id="x" style="width: 5rem;" />
y: <input type="number" min="2" max="5" value="3" onchange="updatePuzzle()" id="y" style="width: 5rem;" />
<button onclick="updatePuzzle(); loop100();">Refresh Challenge</button>
Challenge: <select id="challenge">
<option value="1">Finish Unit (col)</option>
<option value="2">Finish Unit (row)</option>
<option value="3">Finish Unit (blk)</option>
<option value="4">One Spot (col)</option>
<option value="5">One Spot (row)</option>
<option value="6">One Spot (blk)</option>
<option value="7">One Digit in Spot</option>
<option value="8">Subrow in Block (spot)</option>
<option value="9">Subrow in Block (digit)</option>
<option value="10">Subcol in Block (spot)</option>
<option value="11">Subcol in Block (digit)</option>
<option value="12">Subrow in Row (spot)</option>
<option value="13">Subrow in Row (digit)</option>
<option value="14">Subcol in Col (spot)</option>
<option value="15">Subcol in Col (digit)</option>
<option value="16">Naked Pair (spot)</option>
<option value="17">Naked Pair (digit)</option>
<option value="18">Hidden Pair (spot)</option>
<option value="19">Hidden Pair (digit)</option>
</select>
PuzzleStr: <span id="puzzleStr"></span>
</div>
<div id="container">
{% for r in range(1,17) %}
{% for c in range(1,17) %}
<div class="cell row-{{r}} col-{{c}}" id="cell-{{r}}-{{c}}">
</div>
{% endfor %}
{% endfor %}
</div>
<div id="container2">
{% for r in range(1,17) %}
{% for c in range(1,17) %}
<div class="cell row-{{r}} col-{{c}}" id="fillable-{{r}}-{{c}}">
</div>
{% endfor %}
{% endfor %}
</div>
<script src="createSolved.js" ></script>
<script src="challengeSolver.js" ></script>
<script>
var els = document.querySelectorAll('.cell');
els.forEach((el) => {
el.style.display = "none";
el.style.borderRight = "1px dotted gray";
el.style.borderLeft = "1px dotted gray";
el.style.borderTop = "1px dotted gray";
el.style.borderBottom = "1px dotted gray";
el.style.background = "white";
el.addEventListener('click',clickCell);
})
var puzzle;
var puzzleData = {1:0,2:0,3:0,4:0,5:0,'blanks':0};
var selected = {};
var chalID = 1;
function updatePuzzle(clear=true,visual=true,anyChal=false) {
var x = parseInt(document.getElementById('x').value);
var y = parseInt(document.getElementById('y').value);
var puzzleOrdered = random_puzzle(x,y);
for (var i=0;i<20;i++){
if (puzzleOrdered){break;}
puzzleOrdered = random_puzzle(x,y);
}
puzzle = puzzleOrdered.slice();
var digitList = digits.slice();
for (var d in digits){
var dd = Math.floor(Math.random()*digitList.length);
var ddd = digitList[dd];
digitList.splice(dd,1);
for (var i in puzzleOrdered){
if (puzzleOrdered[i]==digits[d]){
puzzle[i]=ddd;
}
}
}
if (clear){
selected = {};
}
var els = document.querySelectorAll('.cell');
els.forEach((el) => {
el.style.display = "none";
el.style.borderRight = "1px dotted gray";
el.style.borderLeft = "1px dotted gray";
el.style.borderTop = "1px dotted gray";
el.style.borderBottom = "1px dotted gray";
if (clear){
el.style.background = "white";
}
})
for (var i=0;i<x*y;i++){
for (var ii=0;ii<x*y;ii++){
var el = document.getElementById('cell-'+(i+1)+"-"+(ii+1));
el.textContent = puzzle[i*x*y+ii];
el.style.display = "inline-block";
if (ii%y == y-1){
el.style.borderRight = "1px solid black";
}
if (ii%y == 0){
el.style.borderLeft = "1px solid black";
}
if (i%x == x-1){
el.style.borderBottom = "1px solid black";
}
if (i%x == 0){
el.style.borderTop = "1px solid black";
}
var el = document.getElementById('fillable-'+(i+1)+"-"+(ii+1));
el.textContent = "";
el.style.display = "inline-block";
if (ii%y == y-1){
el.style.borderRight = "1px solid black";
}
if (ii%y == 0){
el.style.borderLeft = "1px solid black";
}
if (i%x == x-1){
el.style.borderBottom = "1px solid black";
}
if (i%x == 0){
el.style.borderTop = "1px solid black";
}
}
}
if (!clear){return partial_puzzle(visual,anyChal);}
}
function partial_puzzle(visual=true,anyChal=false){
var x = parseInt(document.getElementById('x').value);
var y = parseInt(document.getElementById('y').value);
puzzleData = {1:0,2:0,3:0,4:0,5:0,'blanks':x*y*x*y};
var fills = fillable_puzzle();
var fillColors = {};
for (var i in selected){
if (!selected[i]){continue;}
var s = squares[i];
var v = parseInt(puzzle[i]);
fills[s] = v;
}
//console.log(Date.now());
var updated = true;
var chalFound = false;
while (updated){
updated = false;
var pp = simpleSolve(fills);
pp.sort((a,b) => {return a[2] - b[2];})
var ppp = 1000;
var chalCount = {};
var sqCount = {};
for (var i in pp){
var s = pp[i][0];
var v = pp[i][1];
if (fills[s] == 0){
if (!chalCount[pp[i][2]]){chalCount[pp[i][2]]=[]}
if (pp[i].length > 3){
chalCount[pp[i][2]].push([s,v,pp[i][3]]);
}
else {
chalCount[pp[i][2]].push([s,v]);
}
if (!sqCount[s]){sqCount[s]=0}
sqCount[s]++;
}
}
/*
if (chalCount[1] && chalCount[1].length == 1){
if (chalCount[2] && chalCount[2].length == 1){
if (chalCount[3] && chalCount[3].length == 1){
var js1 = JSON.stringify(chalCount[1]);
var js2 = JSON.stringify(chalCount[2]);
var js3 = JSON.stringify(chalCount[3]);
if (js1 != js2 && js2 != js3 && js1 != js3){
console.log(js1,1);
console.log(js2,2);
console.log(js3,3);
updated = false;
chalFound = true;
pp = false;
}
}
}
}
*/
if (chalCount[chalID] && chalCount[chalID].length == 1){
console.log(sqCount);
if (sqCount[chalCount[chalID][0][0]] == 1 || anyChal){
var js1 = JSON.stringify(chalCount[chalID]);
console.log(js1,chalID);
var rr = chalCount[chalID][0][0].split("-")[0];
var cc = chalCount[chalID][0][0].split("-")[1];
var jsonout;
if (chalCount[chalID][0].length > 2){
jsonout = {fills:fills,chalID:chalID,chalType:chalCount[chalID][0][2],solve:{'n':chalCount[chalID][0][1],'r':rr,'c':cc}};
}
else {
jsonout = {fills:fills,chalID:chalID,solve:{'n':chalCount[chalID][0][1],'r':rr,'c':cc}};
}
console.log(JSON.stringify(jsonout));
updated = false;
chalFound = true;
pp = false;
}
}
for (var i in pp){
if (pp[i][2] > ppp && pp[i][2] > 7){break;}
var s = pp[i][0];
var v = pp[i][1];
if (fills[s] == 0){
/*if (pp[i][2] == 1){
console.log(s,v,pp[i][2]);
updated = false;
chalFound = true;
break;
}*/
fills[s] = v;
fillColors[s] = pp[i][2];
ppp = pp[i][2];
puzzleData[ppp]++;
updated = true;
}
}
}
for (var f in fills){
if (fills[f] != 0){
puzzleData.blanks--;
}
}
//if (puzzleData.blanks == 0){
// console.log(JSON.stringify(puzzleData));
//}
if (puzzleData[3]+puzzleData[4]+puzzleData[5] > 0){
//console.log(JSON.stringify(puzzleData));
}
if (!visual && !chalFound){return false;}
//console.log(Date.now());
for (var i=0;i<x*y;i++){
for (var ii=0;ii<x*y;ii++){
var el = document.getElementById('cell-'+(i+1)+"-"+(ii+1));
var elf = document.getElementById('fillable-'+(i+1)+"-"+(ii+1));
var s = i*x*y+ii;
var v = parseInt(puzzle[s]);
el.textContent = v;
var ss = squares[s];
if (selected[s] || fills[ss]){
el.style.background = "green";
elf.textContent = v;
continue;
}
elf.textContent = "";
if (fills[ss] != 0){
el.style.background = "green";
}
else {
el.style.background = "white";
}
}
}
var chars = ["1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G"]
var pStr = "";
var aout = [];
for (var i in puzzle){
var ss = squares[i];
if (selected[i] || (chalFound && fills[ss])){
pStr += chars[puzzle[i]-1];
aout.push(chars[puzzle[i]-1]);
}
else {
pStr += ".";
aout.push("");
}
}
pStr += ",";
for (var i in puzzle){
pStr += chars[puzzle[i]-1];
}
document.getElementById('puzzleStr').textContent = pStr;
if (chalFound){
return JSON.stringify(aout);
}
//return [fills,puzzle];
return false;
}
function clickCell(evt){
var id = evt.currentTarget.id;
var rc = id.substring(5).split("-");
var r = parseInt(rc[0])-1;
var c = parseInt(rc[1])-1;
var s = r*x*y+c;
var smap = {};
smap[s]=true;
var mirror = document.getElementById('pattern').value;
if (mirror == "horiz"){
var cc = x*y-1-c;
var ss = r*x*y+cc;
smap[ss]=true;
}
else if (mirror == "verti"){
var rr = x*y-1-r;
var ss = rr*x*y+c;
smap[ss]=true;
}
else if (mirror == "diago"){
var rr = x*y-1-c;
var cc = x*y-1-r;
var ss = rr*x*y+cc;
smap[ss]=true;
}
else if (mirror == "ro180"){
var rr = x*y-1-r;
var cc = x*y-1-c;
var ss = rr*x*y+cc;
smap[ss]=true;
}
else if (mirror == "rot90"){
var rr = c;
var cc = x*y-1-r;
var ss = rr*x*y+cc;
smap[ss]=true;
var rrr = cc;
var ccc = x*y-1-rr;
ss = rrr*x*y+ccc;
smap[ss]=true;
var rrrr = ccc;
var cccc = x*y-1-rrr;
ss = rrrr*x*y+cccc;
smap[ss]=true;
}
if (!selected[s]){
for (var ss in smap){
selected[ss]=true;
}
}
else {
for (var ss in smap){
selected[ss]=false;
}
}
partial_puzzle();
}
function loop100() {
console.log(Date.now());
chalID = parseInt(document.getElementById('challenge').value);
var foundChal = false;
for (var i=0;i<100;i++){
selected = {}
var r = 25+Math.floor(Math.random()*15);
for (var ii=0;ii<r;ii++){
selected[Math.floor(Math.random()*x*x*y*y)]=true;
}
var chal = updatePuzzle(false,false);
if (chal){
console.log("success", chalID, r);
console.log(chal);
foundChal = true;
break;
}
}
if (!foundChal){
for (var i=0;i<100;i++){
selected = {}
var r = 25+Math.floor(Math.random()*15);
for (var ii=0;ii<r;ii++){
selected[Math.floor(Math.random()*x*x*y*y)]=true;
}
var chal = updatePuzzle(false,false,true);
if (chal){
console.log("success", chalID, r);
console.log(chal);
foundChal = true;
break;
}
}
}
console.log(Date.now());
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="favicon.png">
<title></title>
<meta name="description" content="" />
<link href="style.css" rel="stylesheet" type="text/css" />
<style>
#container {
display: none;
position: relative;
top:0;
}
#container2 {
display: block;
position: relative;
left:calc(16 * 2rem);
left: 0;
}
@media (orientation: portrait) {
#container2 {
top:calc(16 * 2rem);
top: 0;
left: 0;
}
}
.cell {
border: 1px solid black;
display: inline-block;
height: 2rem;
width: 2rem;
position: absolute;
line-height: 2rem;
text-align: center;
cursor: pointer;
}
.row-1 {
top: calc(2rem * 1);
}
.col-1 {
left: calc(2rem * 1);
}
.row-2 {
top: calc(2rem * 2);
}
.col-2 {
left: calc(2rem * 2);
}
.row-3 {
top: calc(2rem * 3);
}
.col-3 {
left: calc(2rem * 3);
}
.row-4 {
top: calc(2rem * 4);
}
.col-4 {
left: calc(2rem * 4);
}
.row-5 {
top: calc(2rem * 5);
}
.col-5 {
left: calc(2rem * 5);
}
.row-6 {
top: calc(2rem * 6);
}
.col-6 {
left: calc(2rem * 6);
}
.row-7 {
top: calc(2rem * 7);
}
.col-7 {
left: calc(2rem * 7);
}
.row-8 {
top: calc(2rem * 8);
}
.col-8 {
left: calc(2rem * 8);
}
.row-9 {
top: calc(2rem * 9);
}
.col-9 {
left: calc(2rem * 9);
}
.row-10 {
top: calc(2rem * 10);
}
.col-10 {
left: calc(2rem * 10);
}
.row-11 {
top: calc(2rem * 11);
}
.col-11 {
left: calc(2rem * 11);
}
.row-12 {
top: calc(2rem * 12);
}
.col-12 {
left: calc(2rem * 12);
}
.row-13 {
top: calc(2rem * 13);
}
.col-13 {
left: calc(2rem * 13);
}
.row-14 {
top: calc(2rem * 14);
}
.col-14 {
left: calc(2rem * 14);
}
.row-15 {
top: calc(2rem * 15);
}
.col-15 {
left: calc(2rem * 15);
}
.row-16 {
top: calc(2rem * 16);
}
.col-16 {
left: calc(2rem * 16);
}
</style>
</head>
<body>
<div id="menu">
x: <input type="number" min="2" max="5" value="3" onchange="updatePuzzle()" id="x" style="width: 5rem;" />
y: <input type="number" min="2" max="5" value="3" onchange="updatePuzzle()" id="y" style="width: 5rem;" />
<button onclick="updatePuzzle(); loop100();">Refresh Challenge</button>
Challenge: <select id="challenge">
<option value="1">Finish Unit (col)</option>
<option value="2">Finish Unit (row)</option>
<option value="3">Finish Unit (blk)</option>
<option value="4">One Spot (col)</option>
<option value="5">One Spot (row)</option>
<option value="6">One Spot (blk)</option>
<option value="7">One Digit in Spot</option>
<option value="8">Subrow in Block (spot)</option>
<option value="9">Subrow in Block (digit)</option>
<option value="10">Subcol in Block (spot)</option>
<option value="11">Subcol in Block (digit)</option>
<option value="12">Subrow in Row (spot)</option>
<option value="13">Subrow in Row (digit)</option>
<option value="14">Subcol in Col (spot)</option>
<option value="15">Subcol in Col (digit)</option>
<option value="16">Naked Pair (spot)</option>
<option value="17">Naked Pair (digit)</option>
<option value="18">Hidden Pair (spot)</option>
<option value="19">Hidden Pair (digit)</option>
</select>
PuzzleStr: <span id="puzzleStr"></span>
</div>
<div id="container">
<div class="cell row-1 col-1" id="cell-1-1">
</div>
<div class="cell row-1 col-2" id="cell-1-2">
</div>
<div class="cell row-1 col-3" id="cell-1-3">
</div>
<div class="cell row-1 col-4" id="cell-1-4">
</div>
<div class="cell row-1 col-5" id="cell-1-5">
</div>
<div class="cell row-1 col-6" id="cell-1-6">
</div>
<div class="cell row-1 col-7" id="cell-1-7">
</div>
<div class="cell row-1 col-8" id="cell-1-8">
</div>
<div class="cell row-1 col-9" id="cell-1-9">
</div>
<div class="cell row-1 col-10" id="cell-1-10">
</div>
<div class="cell row-1 col-11" id="cell-1-11">
</div>
<div class="cell row-1 col-12" id="cell-1-12">
</div>
<div class="cell row-1 col-13" id="cell-1-13">
</div>
<div class="cell row-1 col-14" id="cell-1-14">
</div>
<div class="cell row-1 col-15" id="cell-1-15">
</div>
<div class="cell row-1 col-16" id="cell-1-16">
</div>
<div class="cell row-2 col-1" id="cell-2-1">
</div>
<div class="cell row-2 col-2" id="cell-2-2">
</div>
<div class="cell row-2 col-3" id="cell-2-3">
</div>
<div class="cell row-2 col-4" id="cell-2-4">
</div>
<div class="cell row-2 col-5" id="cell-2-5">
</div>
<div class="cell row-2 col-6" id="cell-2-6">
</div>
<div class="cell row-2 col-7" id="cell-2-7">
</div>
<div class="cell row-2 col-8" id="cell-2-8">
</div>
<div class="cell row-2 col-9" id="cell-2-9">
</div>
<div class="cell row-2 col-10" id="cell-2-10">
</div>
<div class="cell row-2 col-11" id="cell-2-11">
</div>
<div class="cell row-2 col-12" id="cell-2-12">
</div>
<div class="cell row-2 col-13" id="cell-2-13">
</div>
<div class="cell row-2 col-14" id="cell-2-14">
</div>
<div class="cell row-2 col-15" id="cell-2-15">
</div>
<div class="cell row-2 col-16" id="cell-2-16">
</div>
<div class="cell row-3 col-1" id="cell-3-1">
</div>
<div class="cell row-3 col-2" id="cell-3-2">
</div>
<div class="cell row-3 col-3" id="cell-3-3">
</div>
<div class="cell row-3 col-4" id="cell-3-4">
</div>
<div class="cell row-3 col-5" id="cell-3-5">
</div>
<div class="cell row-3 col-6" id="cell-3-6">
</div>
<div class="cell row-3 col-7" id="cell-3-7">
</div>
<div class="cell row-3 col-8" id="cell-3-8">
</div>
<div class="cell row-3 col-9" id="cell-3-9">
</div>
<div class="cell row-3 col-10" id="cell-3-10">
</div>
<div class="cell row-3 col-11" id="cell-3-11">
</div>
<div class="cell row-3 col-12" id="cell-3-12">
</div>
<div class="cell row-3 col-13" id="cell-3-13">
</div>
<div class="cell row-3 col-14" id="cell-3-14">
</div>
<div class="cell row-3 col-15" id="cell-3-15">
</div>
<div class="cell row-3 col-16" id="cell-3-16">
</div>
<div class="cell row-4 col-1" id="cell-4-1">
</div>
<div class="cell row-4 col-2" id="cell-4-2">
</div>
<div class="cell row-4 col-3" id="cell-4-3">
</div>
<div class="cell row-4 col-4" id="cell-4-4">
</div>
<div class="cell row-4 col-5" id="cell-4-5">
</div>
<div class="cell row-4 col-6" id="cell-4-6">
</div>
<div class="cell row-4 col-7" id="cell-4-7">
</div>
<div class="cell row-4 col-8" id="cell-4-8">
</div>
<div class="cell row-4 col-9" id="cell-4-9">
</div>
<div class="cell row-4 col-10" id="cell-4-10">
</div>
<div class="cell row-4 col-11" id="cell-4-11">
</div>
<div class="cell row-4 col-12" id="cell-4-12">
</div>
<div class="cell row-4 col-13" id="cell-4-13">
</div>
<div class="cell row-4 col-14" id="cell-4-14">
</div>
<div class="cell row-4 col-15" id="cell-4-15">
</div>
<div class="cell row-4 col-16" id="cell-4-16">
</div>
<div class="cell row-5 col-1" id="cell-5-1">
</div>
<div class="cell row-5 col-2" id="cell-5-2">
</div>
<div class="cell row-5 col-3" id="cell-5-3">
</div>
<div class="cell row-5 col-4" id="cell-5-4">
</div>
<div class="cell row-5 col-5" id="cell-5-5">
</div>
<div class="cell row-5 col-6" id="cell-5-6">
</div>
<div class="cell row-5 col-7" id="cell-5-7">
</div>
<div class="cell row-5 col-8" id="cell-5-8">
</div>
<div class="cell row-5 col-9" id="cell-5-9">
</div>
<div class="cell row-5 col-10" id="cell-5-10">
</div>
<div class="cell row-5 col-11" id="cell-5-11">
</div>
<div class="cell row-5 col-12" id="cell-5-12">
</div>
<div class="cell row-5 col-13" id="cell-5-13">
</div>
<div class="cell row-5 col-14" id="cell-5-14">
</div>
<div class="cell row-5 col-15" id="cell-5-15">
</div>
<div class="cell row-5 col-16" id="cell-5-16">
</div>
<div class="cell row-6 col-1" id="cell-6-1">
</div>
<div class="cell row-6 col-2" id="cell-6-2">
</div>
<div class="cell row-6 col-3" id="cell-6-3">
</div>
<div class="cell row-6 col-4" id="cell-6-4">
</div>
<div class="cell row-6 col-5" id="cell-6-5">
</div>
<div class="cell row-6 col-6" id="cell-6-6">
</div>
<div class="cell row-6 col-7" id="cell-6-7">
</div>
<div class="cell row-6 col-8" id="cell-6-8">
</div>
<div class="cell row-6 col-9" id="cell-6-9">
</div>
<div class="cell row-6 col-10" id="cell-6-10">
</div>
<div class="cell row-6 col-11" id="cell-6-11">
</div>
<div class="cell row-6 col-12" id="cell-6-12">
</div>
<div class="cell row-6 col-13" id="cell-6-13">
</div>
<div class="cell row-6 col-14" id="cell-6-14">
</div>
<div class="cell row-6 col-15" id="cell-6-15">
</div>
<div class="cell row-6 col-16" id="cell-6-16">
</div>
<div class="cell row-7 col-1" id="cell-7-1">
</div>
<div class="cell row-7 col-2" id="cell-7-2">
</div>
<div class="cell row-7 col-3" id="cell-7-3">
</div>
<div class="cell row-7 col-4" id="cell-7-4">
</div>
<div class="cell row-7 col-5" id="cell-7-5">
</div>
<div class="cell row-7 col-6" id="cell-7-6">
</div>
<div class="cell row-7 col-7" id="cell-7-7">
</div>
<div class="cell row-7 col-8" id="cell-7-8">
</div>
<div class="cell row-7 col-9" id="cell-7-9">
</div>
<div class="cell row-7 col-10" id="cell-7-10">
</div>
<div class="cell row-7 col-11" id="cell-7-11">
</div>
<div class="cell row-7 col-12" id="cell-7-12">
</div>
<div class="cell row-7 col-13" id="cell-7-13">
</div>
<div class="cell row-7 col-14" id="cell-7-14">
</div>
<div class="cell row-7 col-15" id="cell-7-15">
</div>
<div class="cell row-7 col-16" id="cell-7-16">
</div>
<div class="cell row-8 col-1" id="cell-8-1">
</div>
<div class="cell row-8 col-2" id="cell-8-2">
</div>
<div class="cell row-8 col-3" id="cell-8-3">
</div>
<div class="cell row-8 col-4" id="cell-8-4">
</div>
<div class="cell row-8 col-5" id="cell-8-5">
</div>
<div class="cell row-8 col-6" id="cell-8-6">
</div>
<div class="cell row-8 col-7" id="cell-8-7">
</div>
<div class="cell row-8 col-8" id="cell-8-8">
</div>
<div class="cell row-8 col-9" id="cell-8-9">
</div>
<div class="cell row-8 col-10" id="cell-8-10">
</div>
<div class="cell row-8 col-11" id="cell-8-11">
</div>
<div class="cell row-8 col-12" id="cell-8-12">
</div>
<div class="cell row-8 col-13" id="cell-8-13">
</div>
<div class="cell row-8 col-14" id="cell-8-14">
</div>
<div class="cell row-8 col-15" id="cell-8-15">
</div>
<div class="cell row-8 col-16" id="cell-8-16">
</div>
<div class="cell row-9 col-1" id="cell-9-1">
</div>
<div class="cell row-9 col-2" id="cell-9-2">
</div>
<div class="cell row-9 col-3" id="cell-9-3">
</div>
<div class="cell row-9 col-4" id="cell-9-4">
</div>
<div class="cell row-9 col-5" id="cell-9-5">
</div>
<div class="cell row-9 col-6" id="cell-9-6">
</div>
<div class="cell row-9 col-7" id="cell-9-7">
</div>
<div class="cell row-9 col-8" id="cell-9-8">
</div>
<div class="cell row-9 col-9" id="cell-9-9">
</div>
<div class="cell row-9 col-10" id="cell-9-10">
</div>
<div class="cell row-9 col-11" id="cell-9-11">
</div>
<div class="cell row-9 col-12" id="cell-9-12">
</div>
<div class="cell row-9 col-13" id="cell-9-13">
</div>
<div class="cell row-9 col-14" id="cell-9-14">
</div>
<div class="cell row-9 col-15" id="cell-9-15">
</div>
<div class="cell row-9 col-16" id="cell-9-16">
</div>
<div class="cell row-10 col-1" id="cell-10-1">
</div>
<div class="cell row-10 col-2" id="cell-10-2">
</div>
<div class="cell row-10 col-3" id="cell-10-3">
</div>
<div class="cell row-10 col-4" id="cell-10-4">
</div>
<div class="cell row-10 col-5" id="cell-10-5">
</div>
<div class="cell row-10 col-6" id="cell-10-6">
</div>
<div class="cell row-10 col-7" id="cell-10-7">
</div>
<div class="cell row-10 col-8" id="cell-10-8">
</div>
<div class="cell row-10 col-9" id="cell-10-9">
</div>
<div class="cell row-10 col-10" id="cell-10-10">
</div>
<div class="cell row-10 col-11" id="cell-10-11">
</div>
<div class="cell row-10 col-12" id="cell-10-12">
</div>
<div class="cell row-10 col-13" id="cell-10-13">
</div>
<div class="cell row-10 col-14" id="cell-10-14">
</div>
<div class="cell row-10 col-15" id="cell-10-15">
</div>
<div class="cell row-10 col-16" id="cell-10-16">
</div>
<div class="cell row-11 col-1" id="cell-11-1">
</div>
<div class="cell row-11 col-2" id="cell-11-2">
</div>
<div class="cell row-11 col-3" id="cell-11-3">
</div>
<div class="cell row-11 col-4" id="cell-11-4">
</div>
<div class="cell row-11 col-5" id="cell-11-5">
</div>
<div class="cell row-11 col-6" id="cell-11-6">
</div>
<div class="cell row-11 col-7" id="cell-11-7">
</div>
<div class="cell row-11 col-8" id="cell-11-8">
</div>
<div class="cell row-11 col-9" id="cell-11-9">
</div>
<div class="cell row-11 col-10" id="cell-11-10">
</div>
<div class="cell row-11 col-11" id="cell-11-11">
</div>
<div class="cell row-11 col-12" id="cell-11-12">
</div>
<div class="cell row-11 col-13" id="cell-11-13">
</div>
<div class="cell row-11 col-14" id="cell-11-14">
</div>
<div class="cell row-11 col-15" id="cell-11-15">
</div>
<div class="cell row-11 col-16" id="cell-11-16">
</div>
<div class="cell row-12 col-1" id="cell-12-1">
</div>
<div class="cell row-12 col-2" id="cell-12-2">
</div>
<div class="cell row-12 col-3" id="cell-12-3">
</div>
<div class="cell row-12 col-4" id="cell-12-4">
</div>
<div class="cell row-12 col-5" id="cell-12-5">
</div>
<div class="cell row-12 col-6" id="cell-12-6">
</div>
<div class="cell row-12 col-7" id="cell-12-7">
</div>
<div class="cell row-12 col-8" id="cell-12-8">
</div>
<div class="cell row-12 col-9" id="cell-12-9">
</div>
<div class="cell row-12 col-10" id="cell-12-10">
</div>
<div class="cell row-12 col-11" id="cell-12-11">
</div>
<div class="cell row-12 col-12" id="cell-12-12">
</div>
<div class="cell row-12 col-13" id="cell-12-13">
</div>
<div class="cell row-12 col-14" id="cell-12-14">
</div>
<div class="cell row-12 col-15" id="cell-12-15">
</div>
<div class="cell row-12 col-16" id="cell-12-16">
</div>
<div class="cell row-13 col-1" id="cell-13-1">
</div>
<div class="cell row-13 col-2" id="cell-13-2">
</div>
<div class="cell row-13 col-3" id="cell-13-3">
</div>
<div class="cell row-13 col-4" id="cell-13-4">
</div>
<div class="cell row-13 col-5" id="cell-13-5">
</div>
<div class="cell row-13 col-6" id="cell-13-6">
</div>
<div class="cell row-13 col-7" id="cell-13-7">
</div>
<div class="cell row-13 col-8" id="cell-13-8">
</div>
<div class="cell row-13 col-9" id="cell-13-9">
</div>
<div class="cell row-13 col-10" id="cell-13-10">
</div>
<div class="cell row-13 col-11" id="cell-13-11">
</div>
<div class="cell row-13 col-12" id="cell-13-12">
</div>
<div class="cell row-13 col-13" id="cell-13-13">
</div>
<div class="cell row-13 col-14" id="cell-13-14">
</div>
<div class="cell row-13 col-15" id="cell-13-15">
</div>
<div class="cell row-13 col-16" id="cell-13-16">
</div>
<div class="cell row-14 col-1" id="cell-14-1">
</div>
<div class="cell row-14 col-2" id="cell-14-2">
</div>
<div class="cell row-14 col-3" id="cell-14-3">
</div>
<div class="cell row-14 col-4" id="cell-14-4">
</div>
<div class="cell row-14 col-5" id="cell-14-5">
</div>
<div class="cell row-14 col-6" id="cell-14-6">
</div>
<div class="cell row-14 col-7" id="cell-14-7">
</div>
<div class="cell row-14 col-8" id="cell-14-8">
</div>
<div class="cell row-14 col-9" id="cell-14-9">
</div>
<div class="cell row-14 col-10" id="cell-14-10">
</div>
<div class="cell row-14 col-11" id="cell-14-11">
</div>
<div class="cell row-14 col-12" id="cell-14-12">
</div>
<div class="cell row-14 col-13" id="cell-14-13">
</div>
<div class="cell row-14 col-14" id="cell-14-14">
</div>
<div class="cell row-14 col-15" id="cell-14-15">
</div>
<div class="cell row-14 col-16" id="cell-14-16">
</div>
<div class="cell row-15 col-1" id="cell-15-1">
</div>
<div class="cell row-15 col-2" id="cell-15-2">
</div>
<div class="cell row-15 col-3" id="cell-15-3">
</div>
<div class="cell row-15 col-4" id="cell-15-4">
</div>
<div class="cell row-15 col-5" id="cell-15-5">
</div>
<div class="cell row-15 col-6" id="cell-15-6">
</div>
<div class="cell row-15 col-7" id="cell-15-7">
</div>
<div class="cell row-15 col-8" id="cell-15-8">
</div>
<div class="cell row-15 col-9" id="cell-15-9">
</div>
<div class="cell row-15 col-10" id="cell-15-10">
</div>
<div class="cell row-15 col-11" id="cell-15-11">
</div>
<div class="cell row-15 col-12" id="cell-15-12">
</div>
<div class="cell row-15 col-13" id="cell-15-13">
</div>
<div class="cell row-15 col-14" id="cell-15-14">
</div>
<div class="cell row-15 col-15" id="cell-15-15">
</div>
<div class="cell row-15 col-16" id="cell-15-16">
</div>
<div class="cell row-16 col-1" id="cell-16-1">
</div>
<div class="cell row-16 col-2" id="cell-16-2">
</div>
<div class="cell row-16 col-3" id="cell-16-3">
</div>
<div class="cell row-16 col-4" id="cell-16-4">
</div>
<div class="cell row-16 col-5" id="cell-16-5">
</div>
<div class="cell row-16 col-6" id="cell-16-6">
</div>
<div class="cell row-16 col-7" id="cell-16-7">
</div>
<div class="cell row-16 col-8" id="cell-16-8">
</div>
<div class="cell row-16 col-9" id="cell-16-9">
</div>
<div class="cell row-16 col-10" id="cell-16-10">
</div>
<div class="cell row-16 col-11" id="cell-16-11">
</div>
<div class="cell row-16 col-12" id="cell-16-12">
</div>
<div class="cell row-16 col-13" id="cell-16-13">
</div>
<div class="cell row-16 col-14" id="cell-16-14">
</div>
<div class="cell row-16 col-15" id="cell-16-15">
</div>
<div class="cell row-16 col-16" id="cell-16-16">
</div>
</div>
<div id="container2">
<div class="cell row-1 col-1" id="fillable-1-1">
</div>
<div class="cell row-1 col-2" id="fillable-1-2">
</div>
<div class="cell row-1 col-3" id="fillable-1-3">
</div>
<div class="cell row-1 col-4" id="fillable-1-4">
</div>
<div class="cell row-1 col-5" id="fillable-1-5">
</div>
<div class="cell row-1 col-6" id="fillable-1-6">
</div>
<div class="cell row-1 col-7" id="fillable-1-7">
</div>
<div class="cell row-1 col-8" id="fillable-1-8">
</div>
<div class="cell row-1 col-9" id="fillable-1-9">
</div>
<div class="cell row-1 col-10" id="fillable-1-10">
</div>
<div class="cell row-1 col-11" id="fillable-1-11">
</div>
<div class="cell row-1 col-12" id="fillable-1-12">
</div>
<div class="cell row-1 col-13" id="fillable-1-13">
</div>
<div class="cell row-1 col-14" id="fillable-1-14">
</div>
<div class="cell row-1 col-15" id="fillable-1-15">
</div>
<div class="cell row-1 col-16" id="fillable-1-16">
</div>
<div class="cell row-2 col-1" id="fillable-2-1">
</div>
<div class="cell row-2 col-2" id="fillable-2-2">
</div>
<div class="cell row-2 col-3" id="fillable-2-3">
</div>
<div class="cell row-2 col-4" id="fillable-2-4">
</div>
<div class="cell row-2 col-5" id="fillable-2-5">
</div>
<div class="cell row-2 col-6" id="fillable-2-6">
</div>
<div class="cell row-2 col-7" id="fillable-2-7">
</div>
<div class="cell row-2 col-8" id="fillable-2-8">
</div>
<div class="cell row-2 col-9" id="fillable-2-9">
</div>
<div class="cell row-2 col-10" id="fillable-2-10">
</div>
<div class="cell row-2 col-11" id="fillable-2-11">
</div>
<div class="cell row-2 col-12" id="fillable-2-12">
</div>
<div class="cell row-2 col-13" id="fillable-2-13">
</div>
<div class="cell row-2 col-14" id="fillable-2-14">
</div>
<div class="cell row-2 col-15" id="fillable-2-15">
</div>
<div class="cell row-2 col-16" id="fillable-2-16">
</div>
<div class="cell row-3 col-1" id="fillable-3-1">
</div>
<div class="cell row-3 col-2" id="fillable-3-2">
</div>
<div class="cell row-3 col-3" id="fillable-3-3">
</div>
<div class="cell row-3 col-4" id="fillable-3-4">
</div>
<div class="cell row-3 col-5" id="fillable-3-5">
</div>
<div class="cell row-3 col-6" id="fillable-3-6">
</div>
<div class="cell row-3 col-7" id="fillable-3-7">
</div>
<div class="cell row-3 col-8" id="fillable-3-8">
</div>
<div class="cell row-3 col-9" id="fillable-3-9">
</div>
<div class="cell row-3 col-10" id="fillable-3-10">
</div>
<div class="cell row-3 col-11" id="fillable-3-11">
</div>
<div class="cell row-3 col-12" id="fillable-3-12">
</div>
<div class="cell row-3 col-13" id="fillable-3-13">
</div>
<div class="cell row-3 col-14" id="fillable-3-14">
</div>
<div class="cell row-3 col-15" id="fillable-3-15">
</div>
<div class="cell row-3 col-16" id="fillable-3-16">
</div>
<div class="cell row-4 col-1" id="fillable-4-1">
</div>
<div class="cell row-4 col-2" id="fillable-4-2">
</div>
<div class="cell row-4 col-3" id="fillable-4-3">
</div>
<div class="cell row-4 col-4" id="fillable-4-4">
</div>
<div class="cell row-4 col-5" id="fillable-4-5">
</div>
<div class="cell row-4 col-6" id="fillable-4-6">
</div>
<div class="cell row-4 col-7" id="fillable-4-7">
</div>
<div class="cell row-4 col-8" id="fillable-4-8">
</div>
<div class="cell row-4 col-9" id="fillable-4-9">
</div>
<div class="cell row-4 col-10" id="fillable-4-10">
</div>
<div class="cell row-4 col-11" id="fillable-4-11">
</div>
<div class="cell row-4 col-12" id="fillable-4-12">
</div>
<div class="cell row-4 col-13" id="fillable-4-13">
</div>
<div class="cell row-4 col-14" id="fillable-4-14">
</div>
<div class="cell row-4 col-15" id="fillable-4-15">
</div>
<div class="cell row-4 col-16" id="fillable-4-16">
</div>
<div class="cell row-5 col-1" id="fillable-5-1">
</div>
<div class="cell row-5 col-2" id="fillable-5-2">
</div>
<div class="cell row-5 col-3" id="fillable-5-3">
</div>
<div class="cell row-5 col-4" id="fillable-5-4">
</div>
<div class="cell row-5 col-5" id="fillable-5-5">
</div>
<div class="cell row-5 col-6" id="fillable-5-6">
</div>
<div class="cell row-5 col-7" id="fillable-5-7">
</div>
<div class="cell row-5 col-8" id="fillable-5-8">
</div>
<div class="cell row-5 col-9" id="fillable-5-9">
</div>
<div class="cell row-5 col-10" id="fillable-5-10">
</div>
<div class="cell row-5 col-11" id="fillable-5-11">
</div>
<div class="cell row-5 col-12" id="fillable-5-12">
</div>
<div class="cell row-5 col-13" id="fillable-5-13">
</div>
<div class="cell row-5 col-14" id="fillable-5-14">
</div>
<div class="cell row-5 col-15" id="fillable-5-15">
</div>
<div class="cell row-5 col-16" id="fillable-5-16">
</div>
<div class="cell row-6 col-1" id="fillable-6-1">
</div>
<div class="cell row-6 col-2" id="fillable-6-2">
</div>
<div class="cell row-6 col-3" id="fillable-6-3">
</div>
<div class="cell row-6 col-4" id="fillable-6-4">
</div>
<div class="cell row-6 col-5" id="fillable-6-5">
</div>
<div class="cell row-6 col-6" id="fillable-6-6">
</div>
<div class="cell row-6 col-7" id="fillable-6-7">
</div>
<div class="cell row-6 col-8" id="fillable-6-8">
</div>
<div class="cell row-6 col-9" id="fillable-6-9">
</div>
<div class="cell row-6 col-10" id="fillable-6-10">
</div>
<div class="cell row-6 col-11" id="fillable-6-11">
</div>
<div class="cell row-6 col-12" id="fillable-6-12">
</div>
<div class="cell row-6 col-13" id="fillable-6-13">
</div>
<div class="cell row-6 col-14" id="fillable-6-14">
</div>
<div class="cell row-6 col-15" id="fillable-6-15">
</div>
<div class="cell row-6 col-16" id="fillable-6-16">
</div>
<div class="cell row-7 col-1" id="fillable-7-1">
</div>
<div class="cell row-7 col-2" id="fillable-7-2">
</div>
<div class="cell row-7 col-3" id="fillable-7-3">
</div>
<div class="cell row-7 col-4" id="fillable-7-4">
</div>
<div class="cell row-7 col-5" id="fillable-7-5">
</div>
<div class="cell row-7 col-6" id="fillable-7-6">
</div>
<div class="cell row-7 col-7" id="fillable-7-7">
</div>
<div class="cell row-7 col-8" id="fillable-7-8">
</div>
<div class="cell row-7 col-9" id="fillable-7-9">
</div>
<div class="cell row-7 col-10" id="fillable-7-10">
</div>
<div class="cell row-7 col-11" id="fillable-7-11">
</div>
<div class="cell row-7 col-12" id="fillable-7-12">
</div>
<div class="cell row-7 col-13" id="fillable-7-13">
</div>
<div class="cell row-7 col-14" id="fillable-7-14">
</div>
<div class="cell row-7 col-15" id="fillable-7-15">
</div>
<div class="cell row-7 col-16" id="fillable-7-16">
</div>
<div class="cell row-8 col-1" id="fillable-8-1">
</div>
<div class="cell row-8 col-2" id="fillable-8-2">
</div>
<div class="cell row-8 col-3" id="fillable-8-3">
</div>
<div class="cell row-8 col-4" id="fillable-8-4">
</div>
<div class="cell row-8 col-5" id="fillable-8-5">
</div>
<div class="cell row-8 col-6" id="fillable-8-6">
</div>
<div class="cell row-8 col-7" id="fillable-8-7">
</div>
<div class="cell row-8 col-8" id="fillable-8-8">
</div>
<div class="cell row-8 col-9" id="fillable-8-9">
</div>
<div class="cell row-8 col-10" id="fillable-8-10">
</div>
<div class="cell row-8 col-11" id="fillable-8-11">
</div>
<div class="cell row-8 col-12" id="fillable-8-12">
</div>
<div class="cell row-8 col-13" id="fillable-8-13">
</div>
<div class="cell row-8 col-14" id="fillable-8-14">
</div>
<div class="cell row-8 col-15" id="fillable-8-15">
</div>
<div class="cell row-8 col-16" id="fillable-8-16">
</div>
<div class="cell row-9 col-1" id="fillable-9-1">
</div>
<div class="cell row-9 col-2" id="fillable-9-2">
</div>
<div class="cell row-9 col-3" id="fillable-9-3">
</div>
<div class="cell row-9 col-4" id="fillable-9-4">
</div>
<div class="cell row-9 col-5" id="fillable-9-5">
</div>
<div class="cell row-9 col-6" id="fillable-9-6">
</div>
<div class="cell row-9 col-7" id="fillable-9-7">
</div>
<div class="cell row-9 col-8" id="fillable-9-8">
</div>
<div class="cell row-9 col-9" id="fillable-9-9">
</div>
<div class="cell row-9 col-10" id="fillable-9-10">
</div>
<div class="cell row-9 col-11" id="fillable-9-11">
</div>
<div class="cell row-9 col-12" id="fillable-9-12">
</div>
<div class="cell row-9 col-13" id="fillable-9-13">
</div>
<div class="cell row-9 col-14" id="fillable-9-14">
</div>
<div class="cell row-9 col-15" id="fillable-9-15">
</div>
<div class="cell row-9 col-16" id="fillable-9-16">
</div>
<div class="cell row-10 col-1" id="fillable-10-1">
</div>
<div class="cell row-10 col-2" id="fillable-10-2">
</div>
<div class="cell row-10 col-3" id="fillable-10-3">
</div>
<div class="cell row-10 col-4" id="fillable-10-4">
</div>
<div class="cell row-10 col-5" id="fillable-10-5">
</div>
<div class="cell row-10 col-6" id="fillable-10-6">
</div>
<div class="cell row-10 col-7" id="fillable-10-7">
</div>
<div class="cell row-10 col-8" id="fillable-10-8">
</div>
<div class="cell row-10 col-9" id="fillable-10-9">
</div>
<div class="cell row-10 col-10" id="fillable-10-10">
</div>
<div class="cell row-10 col-11" id="fillable-10-11">
</div>
<div class="cell row-10 col-12" id="fillable-10-12">
</div>
<div class="cell row-10 col-13" id="fillable-10-13">
</div>
<div class="cell row-10 col-14" id="fillable-10-14">
</div>
<div class="cell row-10 col-15" id="fillable-10-15">
</div>
<div class="cell row-10 col-16" id="fillable-10-16">
</div>
<div class="cell row-11 col-1" id="fillable-11-1">
</div>
<div class="cell row-11 col-2" id="fillable-11-2">
</div>
<div class="cell row-11 col-3" id="fillable-11-3">
</div>
<div class="cell row-11 col-4" id="fillable-11-4">
</div>
<div class="cell row-11 col-5" id="fillable-11-5">
</div>
<div class="cell row-11 col-6" id="fillable-11-6">
</div>
<div class="cell row-11 col-7" id="fillable-11-7">
</div>
<div class="cell row-11 col-8" id="fillable-11-8">
</div>
<div class="cell row-11 col-9" id="fillable-11-9">
</div>
<div class="cell row-11 col-10" id="fillable-11-10">
</div>
<div class="cell row-11 col-11" id="fillable-11-11">
</div>
<div class="cell row-11 col-12" id="fillable-11-12">
</div>
<div class="cell row-11 col-13" id="fillable-11-13">
</div>
<div class="cell row-11 col-14" id="fillable-11-14">
</div>
<div class="cell row-11 col-15" id="fillable-11-15">
</div>
<div class="cell row-11 col-16" id="fillable-11-16">
</div>
<div class="cell row-12 col-1" id="fillable-12-1">
</div>
<div class="cell row-12 col-2" id="fillable-12-2">
</div>
<div class="cell row-12 col-3" id="fillable-12-3">
</div>
<div class="cell row-12 col-4" id="fillable-12-4">
</div>
<div class="cell row-12 col-5" id="fillable-12-5">
</div>
<div class="cell row-12 col-6" id="fillable-12-6">
</div>
<div class="cell row-12 col-7" id="fillable-12-7">
</div>
<div class="cell row-12 col-8" id="fillable-12-8">
</div>
<div class="cell row-12 col-9" id="fillable-12-9">
</div>
<div class="cell row-12 col-10" id="fillable-12-10">
</div>
<div class="cell row-12 col-11" id="fillable-12-11">
</div>
<div class="cell row-12 col-12" id="fillable-12-12">
</div>
<div class="cell row-12 col-13" id="fillable-12-13">
</div>
<div class="cell row-12 col-14" id="fillable-12-14">
</div>
<div class="cell row-12 col-15" id="fillable-12-15">
</div>
<div class="cell row-12 col-16" id="fillable-12-16">
</div>
<div class="cell row-13 col-1" id="fillable-13-1">
</div>
<div class="cell row-13 col-2" id="fillable-13-2">
</div>
<div class="cell row-13 col-3" id="fillable-13-3">
</div>
<div class="cell row-13 col-4" id="fillable-13-4">
</div>
<div class="cell row-13 col-5" id="fillable-13-5">
</div>
<div class="cell row-13 col-6" id="fillable-13-6">
</div>
<div class="cell row-13 col-7" id="fillable-13-7">
</div>
<div class="cell row-13 col-8" id="fillable-13-8">
</div>
<div class="cell row-13 col-9" id="fillable-13-9">
</div>
<div class="cell row-13 col-10" id="fillable-13-10">
</div>
<div class="cell row-13 col-11" id="fillable-13-11">
</div>
<div class="cell row-13 col-12" id="fillable-13-12">
</div>
<div class="cell row-13 col-13" id="fillable-13-13">
</div>
<div class="cell row-13 col-14" id="fillable-13-14">
</div>
<div class="cell row-13 col-15" id="fillable-13-15">
</div>
<div class="cell row-13 col-16" id="fillable-13-16">
</div>
<div class="cell row-14 col-1" id="fillable-14-1">
</div>
<div class="cell row-14 col-2" id="fillable-14-2">
</div>
<div class="cell row-14 col-3" id="fillable-14-3">
</div>
<div class="cell row-14 col-4" id="fillable-14-4">
</div>
<div class="cell row-14 col-5" id="fillable-14-5">
</div>
<div class="cell row-14 col-6" id="fillable-14-6">
</div>
<div class="cell row-14 col-7" id="fillable-14-7">
</div>
<div class="cell row-14 col-8" id="fillable-14-8">
</div>
<div class="cell row-14 col-9" id="fillable-14-9">
</div>
<div class="cell row-14 col-10" id="fillable-14-10">
</div>
<div class="cell row-14 col-11" id="fillable-14-11">
</div>
<div class="cell row-14 col-12" id="fillable-14-12">
</div>
<div class="cell row-14 col-13" id="fillable-14-13">
</div>
<div class="cell row-14 col-14" id="fillable-14-14">
</div>
<div class="cell row-14 col-15" id="fillable-14-15">
</div>
<div class="cell row-14 col-16" id="fillable-14-16">
</div>
<div class="cell row-15 col-1" id="fillable-15-1">
</div>
<div class="cell row-15 col-2" id="fillable-15-2">
</div>
<div class="cell row-15 col-3" id="fillable-15-3">
</div>
<div class="cell row-15 col-4" id="fillable-15-4">
</div>
<div class="cell row-15 col-5" id="fillable-15-5">
</div>
<div class="cell row-15 col-6" id="fillable-15-6">
</div>
<div class="cell row-15 col-7" id="fillable-15-7">
</div>
<div class="cell row-15 col-8" id="fillable-15-8">
</div>
<div class="cell row-15 col-9" id="fillable-15-9">
</div>
<div class="cell row-15 col-10" id="fillable-15-10">
</div>
<div class="cell row-15 col-11" id="fillable-15-11">
</div>
<div class="cell row-15 col-12" id="fillable-15-12">
</div>
<div class="cell row-15 col-13" id="fillable-15-13">
</div>
<div class="cell row-15 col-14" id="fillable-15-14">
</div>
<div class="cell row-15 col-15" id="fillable-15-15">
</div>
<div class="cell row-15 col-16" id="fillable-15-16">
</div>
<div class="cell row-16 col-1" id="fillable-16-1">
</div>
<div class="cell row-16 col-2" id="fillable-16-2">
</div>
<div class="cell row-16 col-3" id="fillable-16-3">
</div>
<div class="cell row-16 col-4" id="fillable-16-4">
</div>
<div class="cell row-16 col-5" id="fillable-16-5">
</div>
<div class="cell row-16 col-6" id="fillable-16-6">
</div>
<div class="cell row-16 col-7" id="fillable-16-7">
</div>
<div class="cell row-16 col-8" id="fillable-16-8">
</div>
<div class="cell row-16 col-9" id="fillable-16-9">
</div>
<div class="cell row-16 col-10" id="fillable-16-10">
</div>
<div class="cell row-16 col-11" id="fillable-16-11">
</div>
<div class="cell row-16 col-12" id="fillable-16-12">
</div>
<div class="cell row-16 col-13" id="fillable-16-13">
</div>
<div class="cell row-16 col-14" id="fillable-16-14">
</div>
<div class="cell row-16 col-15" id="fillable-16-15">
</div>
<div class="cell row-16 col-16" id="fillable-16-16">
</div>
</div>
<script src="createSolved.js" ></script>
<script src="challengeSolver.js" ></script>
<script>
var els = document.querySelectorAll('.cell');
els.forEach((el) => {
el.style.display = "none";
el.style.borderRight = "1px dotted gray";
el.style.borderLeft = "1px dotted gray";
el.style.borderTop = "1px dotted gray";
el.style.borderBottom = "1px dotted gray";
el.style.background = "white";
el.addEventListener('click',clickCell);
})
var puzzle;
var puzzleData = {1:0,2:0,3:0,4:0,5:0,'blanks':0};
var selected = {};
var chalID = 1;
function updatePuzzle(clear=true,visual=true,anyChal=false) {
var x = parseInt(document.getElementById('x').value);
var y = parseInt(document.getElementById('y').value);
var puzzleOrdered = random_puzzle(x,y);
for (var i=0;i<20;i++){
if (puzzleOrdered){break;}
puzzleOrdered = random_puzzle(x,y);
}
puzzle = puzzleOrdered.slice();
var digitList = digits.slice();
for (var d in digits){
var dd = Math.floor(Math.random()*digitList.length);
var ddd = digitList[dd];
digitList.splice(dd,1);
for (var i in puzzleOrdered){
if (puzzleOrdered[i]==digits[d]){
puzzle[i]=ddd;
}
}
}
if (clear){
selected = {};
}
var els = document.querySelectorAll('.cell');
els.forEach((el) => {
el.style.display = "none";
el.style.borderRight = "1px dotted gray";
el.style.borderLeft = "1px dotted gray";
el.style.borderTop = "1px dotted gray";
el.style.borderBottom = "1px dotted gray";
if (clear){
el.style.background = "white";
}
})
for (var i=0;i<x*y;i++){
for (var ii=0;ii<x*y;ii++){
var el = document.getElementById('cell-'+(i+1)+"-"+(ii+1));
el.textContent = puzzle[i*x*y+ii];
el.style.display = "inline-block";
if (ii%y == y-1){
el.style.borderRight = "1px solid black";
}
if (ii%y == 0){
el.style.borderLeft = "1px solid black";
}
if (i%x == x-1){
el.style.borderBottom = "1px solid black";
}
if (i%x == 0){
el.style.borderTop = "1px solid black";
}
var el = document.getElementById('fillable-'+(i+1)+"-"+(ii+1));
el.textContent = "";
el.style.display = "inline-block";
if (ii%y == y-1){
el.style.borderRight = "1px solid black";
}
if (ii%y == 0){
el.style.borderLeft = "1px solid black";
}
if (i%x == x-1){
el.style.borderBottom = "1px solid black";
}
if (i%x == 0){
el.style.borderTop = "1px solid black";
}
}
}
if (!clear){return partial_puzzle(visual,anyChal);}
}
function partial_puzzle(visual=true,anyChal=false){
var x = parseInt(document.getElementById('x').value);
var y = parseInt(document.getElementById('y').value);
puzzleData = {1:0,2:0,3:0,4:0,5:0,'blanks':x*y*x*y};
var fills = fillable_puzzle();
var fillColors = {};
for (var i in selected){
if (!selected[i]){continue;}
var s = squares[i];
var v = parseInt(puzzle[i]);
fills[s] = v;
}
//console.log(Date.now());
var updated = true;
var chalFound = false;
while (updated){
updated = false;
var pp = simpleSolve(fills);
pp.sort((a,b) => {return a[2] - b[2];})
var ppp = 1000;
var chalCount = {};
var sqCount = {};
for (var i in pp){
var s = pp[i][0];
var v = pp[i][1];
if (fills[s] == 0){
if (!chalCount[pp[i][2]]){chalCount[pp[i][2]]=[]}
if (pp[i].length > 3){
chalCount[pp[i][2]].push([s,v,pp[i][3]]);
}
else {
chalCount[pp[i][2]].push([s,v]);
}
if (!sqCount[s]){sqCount[s]=0}
sqCount[s]++;
}
}
/*
if (chalCount[1] && chalCount[1].length == 1){
if (chalCount[2] && chalCount[2].length == 1){
if (chalCount[3] && chalCount[3].length == 1){
var js1 = JSON.stringify(chalCount[1]);
var js2 = JSON.stringify(chalCount[2]);
var js3 = JSON.stringify(chalCount[3]);
if (js1 != js2 && js2 != js3 && js1 != js3){
console.log(js1,1);
console.log(js2,2);
console.log(js3,3);
updated = false;
chalFound = true;
pp = false;
}
}
}
}
*/
if (chalCount[chalID] && chalCount[chalID].length == 1){
console.log(sqCount);
if (sqCount[chalCount[chalID][0][0]] == 1 || anyChal){
var js1 = JSON.stringify(chalCount[chalID]);
console.log(js1,chalID);
var rr = chalCount[chalID][0][0].split("-")[0];
var cc = chalCount[chalID][0][0].split("-")[1];
var jsonout;
if (chalCount[chalID][0].length > 2){
jsonout = {fills:fills,chalID:chalID,chalType:chalCount[chalID][0][2],solve:{'n':chalCount[chalID][0][1],'r':rr,'c':cc}};
}
else {
jsonout = {fills:fills,chalID:chalID,solve:{'n':chalCount[chalID][0][1],'r':rr,'c':cc}};
}
console.log(JSON.stringify(jsonout));
updated = false;
chalFound = true;
pp = false;
}
}
for (var i in pp){
if (pp[i][2] > ppp && pp[i][2] > 7){break;}
var s = pp[i][0];
var v = pp[i][1];
if (fills[s] == 0){
/*if (pp[i][2] == 1){
console.log(s,v,pp[i][2]);
updated = false;
chalFound = true;
break;
}*/
fills[s] = v;
fillColors[s] = pp[i][2];
ppp = pp[i][2];
puzzleData[ppp]++;
updated = true;
}
}
}
for (var f in fills){
if (fills[f] != 0){
puzzleData.blanks--;
}
}
//if (puzzleData.blanks == 0){
// console.log(JSON.stringify(puzzleData));
//}
if (puzzleData[3]+puzzleData[4]+puzzleData[5] > 0){
//console.log(JSON.stringify(puzzleData));
}
if (!visual && !chalFound){return false;}
//console.log(Date.now());
for (var i=0;i<x*y;i++){
for (var ii=0;ii<x*y;ii++){
var el = document.getElementById('cell-'+(i+1)+"-"+(ii+1));
var elf = document.getElementById('fillable-'+(i+1)+"-"+(ii+1));
var s = i*x*y+ii;
var v = parseInt(puzzle[s]);
el.textContent = v;
var ss = squares[s];
if (selected[s] || fills[ss]){
el.style.background = "green";
elf.textContent = v;
continue;
}
elf.textContent = "";
if (fills[ss] != 0){
el.style.background = "green";
}
else {
el.style.background = "white";
}
}
}
var chars = ["1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G"]
var pStr = "";
var aout = [];
for (var i in puzzle){
var ss = squares[i];
if (selected[i] || (chalFound && fills[ss])){
pStr += chars[puzzle[i]-1];
aout.push(chars[puzzle[i]-1]);
}
else {
pStr += ".";
aout.push("");
}
}
pStr += ",";
for (var i in puzzle){
pStr += chars[puzzle[i]-1];
}
document.getElementById('puzzleStr').textContent = pStr;
if (chalFound){
return JSON.stringify(aout);
}
//return [fills,puzzle];
return false;
}
function clickCell(evt){
var id = evt.currentTarget.id;
var rc = id.substring(5).split("-");
var r = parseInt(rc[0])-1;
var c = parseInt(rc[1])-1;
var s = r*x*y+c;
var smap = {};
smap[s]=true;
var mirror = document.getElementById('pattern').value;
if (mirror == "horiz"){
var cc = x*y-1-c;
var ss = r*x*y+cc;
smap[ss]=true;
}
else if (mirror == "verti"){
var rr = x*y-1-r;
var ss = rr*x*y+c;
smap[ss]=true;
}
else if (mirror == "diago"){
var rr = x*y-1-c;
var cc = x*y-1-r;
var ss = rr*x*y+cc;
smap[ss]=true;
}
else if (mirror == "ro180"){
var rr = x*y-1-r;
var cc = x*y-1-c;
var ss = rr*x*y+cc;
smap[ss]=true;
}
else if (mirror == "rot90"){
var rr = c;
var cc = x*y-1-r;
var ss = rr*x*y+cc;
smap[ss]=true;
var rrr = cc;
var ccc = x*y-1-rr;
ss = rrr*x*y+ccc;
smap[ss]=true;
var rrrr = ccc;
var cccc = x*y-1-rrr;
ss = rrrr*x*y+cccc;
smap[ss]=true;
}
if (!selected[s]){
for (var ss in smap){
selected[ss]=true;
}
}
else {
for (var ss in smap){
selected[ss]=false;
}
}
partial_puzzle();
}
function loop100() {
console.log(Date.now());
chalID = parseInt(document.getElementById('challenge').value);
var foundChal = false;
for (var i=0;i<100;i++){
selected = {}
var r = 25+Math.floor(Math.random()*15);
for (var ii=0;ii<r;ii++){
selected[Math.floor(Math.random()*x*x*y*y)]=true;
}
var chal = updatePuzzle(false,false);
if (chal){
console.log("success", chalID, r);
console.log(chal);
foundChal = true;
break;
}
}
if (!foundChal){
for (var i=0;i<100;i++){
selected = {}
var r = 25+Math.floor(Math.random()*15);
for (var ii=0;ii<r;ii++){
selected[Math.floor(Math.random()*x*x*y*y)]=true;
}
var chal = updatePuzzle(false,false,true);
if (chal){
console.log("success", chalID, r);
console.log(chal);
foundChal = true;
break;
}
}
}
console.log(Date.now());
}
</script>
</body>
</html>
const fs = require('fs');
const nunjucks = require('nunjucks');
var html = nunjucks.render("genChallenges.html", {});
fs.writeFileSync("index.html", html);
This repl generate some sudoku puzzles that have a particular challenge. Not every puzzle is completely solvable, but it is possible to use a particular strategy to solve one more cell.
To view this on TripleLog, click here.
The index.html file is a generated file from the genChallenges.html template. Choose the challenge type and then click refresh challenge. Every challenge type should eventually return a puzzle but you may need to click a few times. Different sized puzzles may or may not produce challenges.
Add CSS by editing the style.css file that is linked to in the head section or inline edit the style section in the head.
The makehtml.js file will generate the index.html.