- ベストアンサー
数独の正解確認プログラムを作る方法
- 数独の正解確認プログラムを作る方法についてご紹介します。
- 1から9の塊が一つも重複しない場合に正解としますが、実装方法がわかりません。
- tableタグを使用してセルのクラス名を使って同じ塊かどうか確認する方法がわかりません。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
みすった! if (ary.Lgth < M) なおしておいて!
その他の回答 (7)
- babu_baboo
- ベストアンサー率51% (268/525)
縦の列だろうが横の列だろうが配列に抜き出して判定すればよい。 抜き出すのは、関数 C, D, E。 数字が揃っているかの判定は、関数 B。 最近のJSは、Set オブジェクトが使えるので詳しくは https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set これを使うと一度登録された数値が存在するかは Set.prototype.has(value) を使うことで判断出来ます Array.map では、関数の第二引数にインデックスの番号が自動的に割り振られます。それを元にチェックしています。 Array.every は、その配列に与えた関数がすべて条件を満たせば true が返ります。 -- いずれにせよ個々の関数は数行ですので理解しやすいと思うのですが。 せっかく便利な命令が使えるのですから古典的な方法ばかりを探し求めるのは「?」ですよ
- babu_baboo
- ベストアンサー率51% (268/525)
ほんとうにごめんなさい。 子文字で始まる length でした。 おもむくままに書き上げたので、どうかしてましたね。 あと、 let a = new Set ([...ary]); は、 let a = new Set (ary); です。 重ね重ねごめんなさい。 そして解説は他の人にでもお願いしてね。
お礼
ありがたいのですが、これだとどんな方法で実現しているかわかりません。 下記のやり方ではできないでしょうか? 1から9のかたまりが一つもかぶっていなければ、正解にします。 このの作業をテーブルのかたまりの数ぶん実行して、すべてtrueだったら正解とする。
- babu_baboo
- ベストアンサー率51% (268/525)
ary.Length にです。
- babu_baboo
- ベストアンサー率51% (268/525)
const M = 9; const L = Math.sqrt (M); let A = [ 7,6,1, 3,5,2, 8,4,9, 5,8,2, 9,4,1, 3,7,6, 4,9,3, 7,6,8, 2,1,5, 6,2,8, 4,7,3, 9,5,1, 9,7,4, 1,2,5, 6,3,8, 3,1,5, 8,9,6, 4,2,7, 2,5,7, 6,8,4, 1,9,3, 8,3,9, 2,1,7, 5,6,4, 1,4,6, 5,3,9, 7,8,2 ]; function B (ary = []) { if (ary.Lgth < M) return false; let a = new Set ([...ary]); return ary.every ((_, i) => a.has (i + 1)); } function C (row) { let n = row * M; return A.slice (n, n + M); } function D (col) { return [... new Array (M)].map ((_, i) => A[col + i * M]); } function E (area) { const s = i => A.slice (i, i + L); let i = Math.floor (area / 3) * M * L + (area % L) * L; return [].concat (s (i), s (i + M), s (i + M * 2)); } function check () { let ptn = [... new Array (M)].reduce ( (rst, __, i) => rst.concat ([C(i), D(i), E(i)]), []); return ptn.every (p => B(p)); } alert (check () ? "出来た!": "できてな~い!");
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>私の知識不足とソースコードが断片的で、なかなか理解が出来ないのですが、もう少し初心者にもわかるように詳細に教えていただければ幸いです。 何処がわからないのか?がわかれば回答もしやすいのですが。 ただ、「丸々、何もせずに動くものをくれ」だと業務になっちゃうので、 無料で運営されている、このようなコミュニティーでは ちょっと難しい要件になっちゃいますよ!。 >またオリジン補正という単語も分りませんでした。 まず、多くの場合、人間は数字を1から数えていますが、 数字は0から始まります。 9個の箱がある場合 123456789 <- 人間が読む場合の数字は「9」まで 012345678 <- 箱につけているインデクスの番号は「8」まで という風に数字が一つずれるのです。これがオリジンや「0オリジン」 という特性です。 先ほどの、for (i=0;i<9;i++) ... なんとなく「9」という数字があるのでx、9回なんだろうな!とは 感じてもらえたかと思いますが。 i<9 つまり、9未満の数字を満たすときループなので、最大数は8になります。 (ここは、厳密には「型」が関係してますが、今は「8」と思っていいです) 初期値は0ですから、0~8まで「9回」動いているという事です。 数独の場合、1~9の「9回」分ある。 コンピューターは、0~8で、同じ「9回」を表現しているので、 数独から得られる1~9から、1を引いて0~8に変換する工程が 「オリジン補正」となるという事です。 質問の内容は、ようするに「ダブり」があるか?をチェック それが、9回するソースでしたので。 こうなっています。 9回、1以上9以下(未満ではない)をダブりがないなら、 その値は、1~9まで1回使われたものだったことが 保証されます。 これで、判定ロジックが完了ということになります。 OKでしょうか?
- nihonsumire
- ベストアンサー率26% (843/3157)
ご存じとは思いますが、「pythsonで数独を解く」を参照されてはどうでしょうか。そのサイトに「あらゆる数独パズルを解く」がリンクされてます。 参)pythsonで数独を解く https://qiita.com/wsldenli/items/78596c8775a0673f255e
お礼
こちらは見たことはありますが、これは数独のアプリを作る情報ではなく数独の問題を解いてくれるプログラムですよね。 またjavascriptとはだいぶ違くないですか
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>1から9のかたまりが一つもかぶっていなければ、正解にします。 >の部分ですが、whileで釣り返すとしても、 >どうやるかはっきりしません。 要するに、、 for (i=0;i<9;i++) table[i]=0; その後マスに書いてある数字1~9を変数例えば、ansに入れて if (table[ans-1]==0) { table[ans-1]=1; }else{ /* ダブっていた */ } #値からー1しているのは、オリジン補正です。 ってのを9回繰り返せばいいんです。 これを、 縦列、横列でダブりがなければ、成立。 んま、3x3のブロック内での1~9も回してもいいんですが。 ってのを関数化して、 最後までダブりがない時、trueを返し、 ダブりが見つかった時点でfalseで戻れば、完成です。
お礼
私の知識不足とソースコードが断片的で、なかなか理解が出来ないのですが、もう少し初心者にもわかるように詳細に教えていただければ幸いです。 またオリジン補正という単語も分りませんでした。
お礼
ありがとうございます。 どこが間違っているのかいまいちよくわかりませんでした。 const M = 9; const L = Math.sqrt (M); let A = [ 7,6,1, 3,5,2, 8,4,9, 5,8,2, 9,4,1, 3,7,6, 4,9,3, 7,6,8, 2,1,5, 6,2,8, 4,7,3, 9,5,1, 9,7,4, 1,2,5, 6,3,8, 3,1,5, 8,9,6, 4,2,7, 2,5,7, 6,8,4, 1,9,3, 8,3,9, 2,1,7, 5,6,4, 1,4,6, 5,3,9, 7,8,2 ]; function B (ary = []) { if (ary.Lgth < M)//どこがちがうのでしょうか?if (ary.Lgth < M) return false; let a = new Set ([...ary]); return ary.every ((_, i) => a.has (i + 1)); } function C (row) { let n = row * M; return A.slice (n, n + M); } function D (col) { return [... new Array (M)].map ((_, i) => A[col + i * M]); } function E (area) { const s = i => A.slice (i, i + L); let i = Math.floor (area / 3) * M * L + (area % L) * L; return [].concat (s (i), s (i + M), s (i + M * 2)); } function check () { let ptn = [... new Array (M)].reduce ( (rst, __, i) => rst.concat ([C(i), D(i), E(i)]), []); return ptn.every (p => B(p)); } alert (check () ? "出来た!": "できてな~い!");