Created
April 13, 2015 19:57
-
-
Save nw/aed7ed298f9d533e4a1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var games = [ | |
"4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......", | |
"52...6.........7.13...........4..8..6......5...........418.........3..2...87.....", | |
"6.....8.3.4.7.................5.4.7.3..2.....1.6.......2.....5.....8.6......1....", | |
"48.3............71.2.......7.5....6....2..8.............1.76...3.....4......5....", | |
"....14....3....2...7..........9...3.6.1.............8.2.....1.4....5.6.....7.8...", | |
"......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.", | |
"6.2.5.........3.4..........43...8....1....2........7..5..27...........81...6.....", | |
".524.........7.1..............8.2...3.....6...9.5.....1.6.3...........897........", | |
"6.2.5.........4.3..........43...8....1....2........7..5..27...........81...6.....", | |
".923.........8.1...........1.7.4...........658.........6.5.2...4.....7.....9.....", | |
"6..3.2....5.....1..........7.26............543.........8.15........4.2........7..", | |
".6.5.1.9.1...9..539....7....4.8...7.......5.8.817.5.3.....5.2............76..8...", | |
"..5...987.4..5...1..7......2...48....9.1.....6..2.....3..6..2.......9.7.......5..", | |
"3.6.7...........518.........1.4.5...7.....6.....2......2.....4.....8.3.....5.....", | |
"1.....3.8.7.4..............2.3.1...........958.........5.6...7.....8.2...4.......", | |
"6..3.2....4.....1..........7.26............543.........8.15........4.2........7..", | |
"....3..9....2....1.5.9..............1.2.8.4.6.8.5...2..75......4.1..6..3.....4.6.", | |
"45.....3....8.1....9...........5..9.2..7.....8.........1..4..........7.2...6..8..", | |
".237....68...6.59.9.....7......4.97.3.7.96..2.........5..47.........2....8.......", | |
"..84...3....3.....9....157479...8........7..514.....2...9.6...2.5....4......9..56", | |
".98.1....2......6.............3.2.5..84.........6.........4.8.93..5...........1..", | |
"..247..58..............1.4.....2...9528.9.4....9...1.........3.3....75..685..2...", | |
"4.....8.5.3..........7......2.....6.....5.4......1.......6.3.7.5..2.....1.9......", | |
".2.3......63.....58.......15....9.3....7........1....8.879..26......6.7...6..7..4", | |
"1.....7.9.4...72..8.........7..1..6.3.......5.6..4..2.........8..53...7.7.2....46", | |
"4.....3.....8.2......7........1...8734.......6........5...6........1.4...82......", | |
".......71.2.8........4.3...7...6..5....2..3..9........6...7.....8....4......5....", | |
"6..3.2....4.....8..........7.26............543.........8.15........8.2........7..", | |
".47.8...1............6..7..6....357......5....1..6....28..4.....9.1...4.....2.69.", | |
"......8.17..2........5.6......7...5..1....3...8.......5......2..4..8....6...3....", | |
"38.6.......9.......2..3.51......5....3..1..6....4......17.5..8.......9.......7.32", | |
"...5...........5.697.....2...48.2...25.1...3..8..3.........4.7..13.5..9..2...31..", | |
".2.......3.5.62..9.68...3...5..........64.8.2..47..9....3.....1.....6...17.43....", | |
".8..4....3......1........2...5...4.69..1..8..2...........3.9....6....5.....2.....", | |
"..8.9.1...6.5...2......6....3.1.7.5.........9..4...3...5....2...7...3.8.2..7....4", | |
"4.....5.8.3..........7......2.....6.....5.8......1.......6.3.7.5..2.....1.8......", | |
"1.....3.8.6.4..............2.3.1...........958.........5.6...7.....8.2...4.......", | |
"1....6.8..64..........4...7....9.6...7.4..5..5...7.1...5....32.3....8...4........", | |
"249.6...3.3....2..8.......5.....6......2......1..4.82..9.5..7....4.....1.7...3...", | |
"...8....9.873...4.6..7.......85..97...........43..75.......3....3...145.4....2..1", | |
"...5.1....9....8...6.......4.1..........7..9........3.8.....1.5...2..4.....36....", | |
"......8.16..2........7.5......6...2..1....3...8.......2......7..3..8....5...4....", | |
".476...5.8.3.....2.....9......8.5..6...1.....6.24......78...51...6....4..9...4..7", | |
".....7.95.....1...86..2.....2..73..85......6...3..49..3.5...41724................", | |
".4.5.....8...9..3..76.2.....146..........9..7.....36....1..4.5..6......3..71..2..", | |
".834.........7..5...........4.1.8..........27...3.....2.6.5....5.....8........1..", | |
"..9.....3.....9...7.....5.6..65..4.....3......28......3..75.6..6...........12.3.8", | |
".26.39......6....19.....7.......4..9.5....2....85.....3..2..9..4....762.........4", | |
"2.3.8....8..7...........1...6.5.7...4......3....1............82.5....6...1.......", | |
"6..3.2....1.....5..........7.26............843.........8.15........8.2........7..", | |
"1.....9...64..1.7..7..4.......3.....3.89..5....7....2.....6.7.9.....4.1....129.3.", | |
".........9......84.623...5....6...453...1...6...9...7....1.....4.5..2....3.8....9", | |
".2....5938..5..46.94..6...8..2.3.....6..8.73.7..2.........4.38..7....6..........5", | |
"9.4..5...25.6..1..31......8.7...9...4..26......147....7.......2...3..8.6.4.....9.", | |
"...52.....9...3..4......7...1.....4..8..453..6...1...87.2........8....32.4..8..1.", | |
"53..2.9...24.3..5...9..........1.827...7.........981.............64....91.2.5.43.", | |
"1....786...7..8.1.8..2....9........24...1......9..5...6.8..........5.9.......93.4", | |
"....5...11......7..6.....8......4.....9.1.3.....596.2..8..62..7..7......3.5.7.2..", | |
".47.2....8....1....3....9.2.....5...6..81..5.....4.....7....3.4...9...1.4..27.8..", | |
"......94.....9...53....5.7..8.4..1..463...........7.8.8..7.....7......28.5.26....", | |
".2......6....41.....78....1......7....37.....6..412....1..74..5..8.5..7......39..", | |
"1.....3.8.6.4..............2.3.1...........758.........7.5...6.....8.2...4.......", | |
"2....1.9..1..3.7..9..8...2.......85..6.4.........7...3.2.3...6....5.....1.9...2.5", | |
"..7..8.....6.2.3...3......9.1..5..6.....1.....7.9....2........4.83..4...26....51.", | |
"...36....85.......9.4..8........68.........17..9..45...1.5...6.4....9..2.....3...", | |
"34.6.......7.......2..8.57......5....7..1..2....4......36.2..1.......9.......7.82", | |
"......4.18..2........6.7......8...6..4....3...1.......6......2..5..1....7...3....", | |
".4..5..67...1...4....2.....1..8..3........2...6...........4..5.3.....8..2........", | |
".......4...2..4..1.7..5..9...3..7....4..6....6..1..8...2....1..85.9...6.....8...3", | |
"8..7....4.5....6............3.97...8....43..5....2.9....6......2...6...7.71..83.2", | |
".8...4.5....7..3............1..85...6.....2......4....3.26............417........", | |
"....7..8...6...5...2...3.61.1...7..2..8..534.2..9.......2......58...6.3.4...1....", | |
"......8.16..2........7.5......6...2..1....3...8.......2......7..4..8....5...3....", | |
".2..........6....3.74.8.........3..2.8..4..1.6..5.........1.78.5....9..........4.", | |
".52..68.......7.2.......6....48..9..2..41......1.....8..61..38.....9...63..6..1.9", | |
"....1.78.5....9..........4..2..........6....3.74.8.........3..2.8..4..1.6..5.....", | |
"1.......3.6.3..7...7...5..121.7...9...7........8.1..2....8.64....9.2..6....4.....", | |
"4...7.1....19.46.5.....1......7....2..2.3....847..6....14...8.6.2....3..6...9....", | |
"......8.17..2........5.6......7...5..1....3...8.......5......2..3..8....6...4....", | |
"963......1....8......2.5....4.8......1....7......3..257......3...9.2.4.7......9..", | |
"15.3......7..4.2....4.72.....8.........9..1.8.1..8.79......38...........6....7423", | |
"..........5724...98....947...9..3...5..9..12...3.1.9...6....25....56.....7......6", | |
"....75....1..2.....4...3...5.....3.2...8...1.......6.....1..48.2........7........", | |
"6.....7.3.4.8.................5.4.8.7..2.....1.3.......2.....5.....7.9......1....", | |
"....6...4..6.3....1..4..5.77.....8.5...8.....6.8....9...2.9....4....32....97..1..", | |
".32.....58..3.....9.428...1...4...39...6...5.....1.....2...67.8.....4....95....6.", | |
"...5.3.......6.7..5.8....1636..2.......4.1.......3...567....2.8..4.7.......2..5..", | |
".5.3.7.4.1.........3.......5.8.3.61....8..5.9.6..1........4...6...6927....2...9..", | |
"..5..8..18......9.......78....4.....64....9......53..2.6.........138..5....9.714.", | |
"..........72.6.1....51...82.8...13..4.........37.9..1.....238..5.4..9.........79.", | |
"...658.....4......12............96.7...3..5....2.8...3..19..8..3.6.....4....473..", | |
".2.3.......6..8.9.83.5........2...8.7.9..5........6..4.......1...1...4.22..7..8.9", | |
".5..9....1.....6.....3.8.....8.4...9514.......3....2..........4.8...6..77..15..6.", | |
".....2.......7...17..3...9.8..7......2.89.6...13..6....9..5.824.....891..........", | |
"3...8.......7....51..............36...2..4....7...........6.13..452...........8.." | |
]; | |
games.forEach(function(game){ | |
var start = Date.now(); | |
var board = solve(game); | |
if(!board) return; | |
display(board); | |
var solved = search(board); | |
var stop = Date.now(); | |
display(solved); | |
console.log(game); | |
console.log('solved in', stop - start, 'ms'); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var digits = '123456789' | |
, rows = 'ABCDEFGHI'.split('') | |
, cols = digits.split('') | |
, squares = cross(rows, cols) | |
, units = ['ABC', 'DEF', 'GHI'].map(function(rs){ | |
return ['123', '456', '789'].map(cross.bind(null, rs)) | |
}).reduce(concat) | |
, unitlist = union([ | |
cols.map(cross.bind(null, rows)), | |
rows.map(function(r){ return cross(r, cols) }), | |
units ]) | |
, peers = zip(squares, squares.map(function(s){ | |
return union(unitlist.filter(contains.bind(null, s))) | |
.filter(function(c){ return c !== s }) | |
})); | |
function solve(grid) { | |
var chars = grid.split('').filter(function(c){ | |
return contains(c, digits + '0.') | |
}); | |
if(chars.length !== 81) return false; | |
var vals = zip(squares, squares.map(function(){ return digits })); | |
return squares.some(function(s, i){ | |
return (contains(chars[i], digits)) ? !assign(vals, s, chars[i]) : false; | |
}) ? false : vals; | |
} | |
function assign(values, s, d){ | |
return values[s].replace(d, '').split('').every(function(d2){ | |
return eliminate(values, s, d2); | |
}) ? values : false; | |
} | |
function eliminate(values, s, d){ | |
if(!contains(d, values[s])) return values; | |
values[s] = values[s].replace(d, ''); | |
if(values[s].length === 0) return false; | |
else if(values[s].length === 1) { | |
var d2 = values[s]; | |
if(!peers[s].every(function(s2){ | |
return eliminate(values, s2, d2); | |
})) return false | |
} | |
return values | |
} | |
function search(board){ | |
if(!board) return false; | |
if(squares.every(function(s){ | |
return board[s].length === 1; | |
})) return board; // solved! | |
var s = squares.map(function(s){ return {k: s, l: board[s].length} }) | |
.filter(function(p){ return p.l > 1 }) | |
.sort(function(a, b){ return b.l - a.l }) | |
.pop().k; | |
var digits = board[s].split(''); | |
for(var i = 0; i < digits.length; i++){ | |
var res = search(assign(copy(board), s, digits[i])); | |
if(res) return res; | |
} | |
return false; | |
} | |
function display(board) { | |
var width = 1 + Math.max.apply([], squares.map(function(s){ | |
return board[s].length | |
})); | |
var seg = repeat('-', width*3); | |
var line = [seg, seg, seg].join('+'); | |
console.log('\n'+ line); | |
rows.forEach(function(r){ | |
console.log(cols.map(function(c){ | |
return center(board[r+c], width) + (contains(c, '36') ? '|' : '') | |
}).join('')) | |
if(contains(r, 'CF')) console.log(line); | |
}) | |
console.log(line + '\n'); | |
} | |
function repeat(str, times){ | |
return Array(times + 1).join(str); | |
} | |
function center(str, width) { | |
var diff = width - str.length; | |
str = repeat(' ', Math.floor(diff / 2)) + str; | |
return str + repeat(' ', width - str.length); | |
} | |
function cross(A, B){ | |
var c = []; | |
splat(A).forEach(function(a){ | |
splat(B).forEach(function(b){ | |
c.push(a+b); | |
}) | |
}) | |
return c; | |
} | |
function splat(a){ | |
return Array.isArray(a) ? a : a.split(''); | |
} | |
function union(arr) { | |
return [].concat.apply([], arr); | |
} | |
function concat(p, c){ | |
return (p || []).concat(c) | |
} | |
function contains(v, a){ | |
return a.indexOf(v) !== -1; | |
} | |
function zip(A, B) { | |
var obj = {}; | |
A.forEach(function(a, i){ | |
obj[a] = B[i]; | |
}); | |
return obj; | |
} | |
function copy(a){ | |
var o = {}; | |
for(var i in a) o[i] = a[i]; | |
return o; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment