今日も1日プログラム

rar形式のアーカイブを解凍しようとすると、
何故かプログラムの実行候補にterapadが挙がってた。
テキストエディタが何故に……。


今日も1日プログラム。
一つの事に没頭すると周りが見えなくなるのは中学の頃から変わってないなぁ。
と、散髪逝こうと思ってたけど逝かなかった今日この頃。


さて、初級レベルの簡単な問題なら解けるプログラムが出来ました。
まだまだいろんな技法があるからそれを打ち込めばもっと難しい問題にも対応出来るようになるでしょう。

実際紙で解くときに行うことをプログラムで表現するのは難しいな。
かなり重要な技法を作りたいのですが上手く構築できない。


今日の進展は、
・変数が違うだけで内容は同じ処理を一つの関数に纏めた
DOSだと500行くらいしか見れないから途中経過を見れるように全てのログを吐き出せるようにした
・昨日挙げたコードを応用して、大枠内で同じ処理をするための関数を作った
こんなところか。
・1手の定義を1ループから1進展にした
・評価関数の修正、及び新規作成
こんなところか。


今日のソースは昨日の応用版


// 大枠内の同一の候補の数を数えて、一つしか存在しない候補があれば、
// その候補のあるマスの他の候補を削減する
bool CountCandiFrame(){
int i, j , k, l, m, n, count[ 9 ];
bool count_candi[ 9 ], proc[ 3 ][ 3 ][ 9 ];

for( I3LOOP ){
for( J3LOOP ){
// 初期化
for( K9LOOP ){
count[ k ] = 0;
count_candi[ k ] = true; // 初期値はtrueにしておく
}

// まず、それぞれの数が候補としていくつ挙げられているかを調べる
for( K3LOOP ){
for( L3LOOP ){
for( M9LOOP ){
if( candi[ i * 3 + k ][ j * 3 + l ][ m ] == true ) count[ m ]++;
}
}
}

// 挙げられた候補の中で、一つしか存在しないものを記録
for( L9LOOP ){
if( count[ l ] == 1 ) count_candi[ l ] = false; // 一つしか存在しないものはfalse
}

//----------------------------------------------------------------------------
// それぞれのマスの候補と一つしか存在しない候補から、
// 一つしか存在しない候補のあるマスを選出し、そのマスの他の候補を除去する
//----------------------------------------------------------------------------
// まず、それぞれのマスと一つしか存在しない候補の論理積を取る
for( K3LOOP ){
for( L3LOOP ){
for( M9LOOP ){
proc[ k ][ l ][ m ] = candi[ i * 3 + k ][ j * 3 + l ][ m ] & count_candi[ m ];
}
}
}

// 元のマスの候補と論理積を取った値を比較して一致しなければ、
// そのマスは一つしか存在しない候補を含む
for( K3LOOP ){
for( L3LOOP ){
for( M9LOOP ){
if( proc[ k ][ l ][ m ] != candi[ i * 3 + k ][ j * 3 + l ][ m ] ){
// 一致しなければ、
// 元のマスの候補と論理積を取った値の排他的論理和で一致しない候補以外を除去する
for( n = 0; n < 9; n++ ){
candi[ i * 3 + k ][ j * 3 + l ][ n ] ^= proc[ k ][ l ][ n ];
}
// 同一のマスに一つしか存在しない候補が複数あることはありえないのでbreakで抜ける
break; // これはあっても無くても動作に関係は無い
}
}
}
}
}
}

return Result();
}

昨日のコードは1行若しくは1列の検査を行うものでしたが、
今日のは3 * 3マス内での検査をします。

3 * 3の大枠の中の3 * 3マスを調べる、ということをしているので、
昨日よりも更にfor文が多くなりました。
マスを一意に特定するだけでも4重が必須。
6重とか??。

ソースコードを読む樹が失せますよね。
傍から見て6重の繰り返し構造を理解出来るのか。

QACだと入れ子構造が5重になると警告を吐くらしいです。
警告くらいまくりですね。


簡単な問題なら解けたので、実際に解いたものを上げてみます。

処理結果
こんなに長い文書でも1秒以内試行して結果を吐き出してくれるコンピュータは凄いですね。
改めて思いますよ。

これ、実際に人間が解いていく過程と似ていますか?
まぁ少なくとも私は初手が全てのマスの候補を列挙する、なんてことはしませんね。
ただ、問題の中に多く登場する数を探して、そこから探していくというのは果てしなくめんdなのでやりたくありません。
人間はそうするしかないので、そういう意味では人間的な解き方ではないです。


先日作っているものは晒さないとか言ってましたが、
嘘吐きまくりですね。
発言に一貫性の無い男。


こういうの作ってると、私って一応プログラムの勉強したんだなとつくづく思います。