実装化に当たっての方針
これまでプログラミングを考えるという観点から、AIを用いてナンバープレイスを解くというミッションに挑戦してきました。
ここに至るまで、ナンプレ解法を2桁サポートすることを目指してHTMLを使って実装化に励んできましたが先日、10個目の『XY-WING』の動作確認を終えたところです。
さて、モノを作るには製造技術を持っていなければなりませんが、品質の高い商品を作るには最終的な製造技術があれば事足りるというわけではありません。ナンプレは1~9の数字を扱い、3つに限定する処理が極めて多いです。縦、横、ブロックと常に3に関わっています。
ナンプレ解法の三国同盟、隠れ三国同盟、BoxLine、XY-WINGなどにおいて、『3マスに限定された3つの候補』という条件がしばしば出現します。
実装化に当たり3にまつわる事柄について整理しておきます。
3つに限定された3つの候補
9個のなかから3個を選ぶ組み合わせは84通りあります。123から789まであり、求め方を含めて下記に示されます。
9C3=84
9個の中から3個を選び3限定を成立させる組み合わせは次の84通り
普遍化とは
以前、当サイトのナンプレ三国同盟実装するにおいて、普遍化の部分で123以外の数字を出現回数を調べて123に引き当て普遍化テーブルと突き合わせると述べましたが、この方法は適切でありませんでした。
普遍化とは多くの例証があるとき、すべてのケースに合致する法則を見出して一つの例題で説明するときに適用するものです。
あらゆる事象に応用できない場合は誤りです。今回の記事により訂正いたします。
9C3=84はそれほど大きな情報量ではないので、起こりうるすべてを定数として用意する方式に変更しました。定数は1, 2, 3と3個1組で使われることもありますが、12, 13, 23と2桁で利用される場合が多くこの他にも三国同盟においては12, 13, 123や23, 123, 123など8種類のバリエーションが存在します。これらのテーブルを追加するとさらに情報量が膨らむので必要になったときに生成して利用しています。
基本形の123から2桁の組合せ(12, 13, 23)や三国同盟を成立する候補の組合せは平易な方法で生成することができます。
まとめ
数多くのバリエーションがあるとき、代表的な値で全体を説明可能な場合、普遍化して少ない情報で代替できますが、そうでない場合はすべてを例証として挙げることが手堅い手法と言えます。
おまけ
9個のなかから3個を選ぶ組み合わせを表示するHTML関数コードをおまけとして以下に掲載して終わりにします。
SyntaxHighlighter Evolvedプラグインを有効化するのを忘れていました。あぁ反省!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<Div style="margin:0 auto; width:600px; height:280px; font-size:18px; background:ivory; border:1px solid green;">
<div style="text-align:center;">9個の中から<b>3個を選び3限定</b>を成立させる組み合わせは次の<b>84</b>通り</div>
<div id="item" style="text-align:left; margin:20px; width100%; height:auto; font-size:16px;"></div>
</Div>
<script type="text/javascript">
var vMax=ary=0;
const combination = (nums, k) => { //numsで指定された文字からk文字を選ぶ組み合わせ配列を求める
let ans = []; //1,2,3,4 ===> 1,2 1,3 1,4 2,3 2,4 3,4
if(nums.length > vMax) vMax=nums.length;
console.log("nums.length="+nums.length, k, vMax);
if (nums.length < k) {
return []
}
if (k === 1) {
for (let i = 0; i < nums.length; i++) {
ans[i] = [nums[i]];
}
} else {
for (let i = 0; i < nums.length - k + 1; i++) {
let row = combination(nums.slice(i + 1), k - 1);
for (let j = 0; j < row.length; j++) { //ここで指定された文字からk文字を選んでいく
ans.push([nums[i]].concat(row[j]));
}
}
}
return ans;
}
for(var i=3; i<=9; ++i){
var number=new Array(i);
for(var j=0; j<i; ++j) number[j]=j+1; //1, 2, 3, 4, 5, 6
ary = combination(number, 3);
console.log(i+" "+letter2(ary.length)+" "+vMax+"C3="+JSON.stringify(ary));//'a', 'b', 'c' ===> ["a","b"],["a","c"],["b","c"]]
}
//document.getElementById("item").innerHTML = JSON.stringify(ary);
console.log(ary.length, ary[0], ary[83]);
for(var i=0; i<ary.length; ++i){
document.getElementById("item").innerHTML += ary[i] + " "
}
function letter2(n) {return (" "+n).slice(-2);} <!-- send ' 1' -->
</script>
</html>