ナンバープレイス

簡単な問題なら解けるレベルまで到達。
まだ全然進んでないんですが。

一応解けるようになったのでソースコードを晒してみる。
プログラムなんて1年以上触ってないようなものだし、
経験自体も乏しいので期待してはいけませんよ(死


成長過程

初期バージョン
これはネタですk


for( i = 0; i < 9; i++ ){
if( count[ i ] == 1 ){
for( j = 0; j < 9; j++ ){
if( tuple[ j ][ i ] == true ){
for( k = 0; k < 9; k++ ){
if( tuple[ j ][ i ] == true ) tuple[ j ][ k ]= false;
}
}
}
}
}
因みに上にも5行くらいの処理がありましたが残ってません。

眠い中打ってたのでかなり酷いです。
どのくらい酷いかというと、思わずここで晒したくなるくらい(何


これを打ち直したバージョン2


for( i = 0; i < 9; i++ ){
// 行単位で処理するので、ややこしいがここから一つの処理になる
for( j = 0; j < 9; j++ ){
for( k = 0; k < 9; k++ ){
if( candi[ i ][ j ][ k ] == true ) count[ k ]++;
}
}

for( l = 0; l < 9; l++ ){
if( count[ l ] == 1 ){
for( j = 0; j < 9; j++ ){
for( k = 0; k < 9; k++ ){
if( l != k ) candi[ i ][ j ][ k ] = false;
}
}
}
}
}

上5行くらいの記述が追加されたので前より冗長になったような感じ。
このふざけた入れ子構造はどうにかならんのか。
こんなコードを書いたら殴られるんじゃないか?


完成バージョン


for( I9LOOP ){
// 初期化
for( J9LOOP ){
count[ j ] = 0;
count_candi[ j ] = true; // 初期値はtrueにしておく
}

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

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

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

// 元のマスの候補と論理積を取った値を比較して一致しなければ、
// そのマスは一つしか存在しない候補を含む
for( J9LOOP ){
for( K9LOOP ){
if( proc[ j ][ k ] != candi[ i ][ j ][ k ] ){
// 一致しなければ、元のマスの候補と論理積を取った値の排他的論理和で一致しない候補以外を除去する
for( L9LOOP ){
candi[ i ][ j ][ l ] ^= proc[ j ][ l ];
}
// 同一のマスに一つしか存在しない候補が複数あることはありえないのでbreakで抜ける
break;
}
}
}
}

これで大分綺麗になりましたね。
……どこがだよ(死
2番目から比べると劇的に変化しています。


for文の中がマクロになってるのがポイント。
for文があまりにも多すぎるので打ち込むのがかなりめんd
#define最高だよ。

因みにナンバープレイスの解放をプログラムに命令しているので、
このあと更に列で見た場合と大枠で見た場合も入力する必要があります。
列の場合は行と処理が同じなので関数を使えば纏められそうな感じがするのですが、
for文の順序のiとjが入れ替わるのでこれを入れるのはめんdそうd
値渡しとか参照渡しがよく分からんのですよ。

まぁこの場合は
func( i, j )
とするか、
func( j, i )
とするかで区別出来そうな感じですg
処理の結果を格納する配列自体はグローバル変数だからこれでいけるかな。


またしても専門的な内容でごめんね。
また文句言われるy