js数独ソルバ日本語版
code: solver_ja.js
Array.prototype.全て = Array.prototype.every;
Array.prototype.どれか = Array.prototype.some;
const 切捨 = Math.floor;
// Wikipediaより引用
const 数独の問題例 = `
5 3 . . 7 . . . .
6 . . 1 9 5 . . .
. 9 8 . . . . 6 .
8 . . . 6 . . . 3
4 . . 8 . 3 . . 1
7 . . . 2 . . . 6
. 6 . . . . 2 8 .
. . . 4 1 9 . . 5
. . . . 8 . . 7 9
`;
const 盤面 = 数独の問題例.replace(/\s/g,'').replace('.','0').split('').map(e=>parseInt(e));
const 幅 = 9; 高さ = 9;
const マスの数 = 幅 * 高さ;
const ブロック幅 = 3;
// 左上から0,1,2,...,80で表されるマスIdを行,列,太枠グループに対応
const 列 = (マスId) => 切捨(マスId / 幅);
const 行 = (マスId) => (マスId % 幅);
// 左上から数えて何番目のブロックか
const ブロック = (マスId) => 切捨(列(マスId)/ブロック幅)*ブロック幅+ 切捨(行(マスId)/ブロック幅);
const 次の = マス => マス + 1;
const 記入済の = マスId => 盤面マスId > 0; // 条件グループ(列, 行, ブロック)のどれかにnが入っている
盤面.どれか((マスの数字, マスId) => g(指定マスId) === g(マスId) && マスの数字 === 入れる数字)
);
const 解答作成 = マスId => {
// 盤面が完成している
if (マスId === マスの数) { return true; }
// 最初から記入済の場合, 次のマスをチェック
if (記入済の(マスId)) { return 解答作成(次の(マスId)); }
// どれかの数字を入れて重複せず, それ以降も数字を記入することができれば
if (入る数字.どれか(数字 => !重複(マスId, 数字) && (盤面マスId = 数字, 解答作成(次の(マスId))))) { // 正しい盤面
return true;
}
else {
// そうでなければ盤面を消して一つ戻し, 他の数字をチェック
return false;
}
}
console.log(数独の問題例);
解答作成(0);
console.log(盤面.join('').replace(/(.{9})/g,'$1\n').replace(/(.)/g,' $1'));
実行例