ヌメロン検証アルゴリズム
ヌメロンの検証アルゴリズムについて説明します。
作り始めたころはイフ文だらけで頭がパンクしそうになったけど、落ち込んで寝ていたらアイデアが浮かんだ。
『どうせコンピュータにやらせるんだから全部試させてみりゃ良いんじゃね?』
ここですね肝は。どうしても最初は自分の思考アルゴリズムをそのままコンピュータに載せようとしちゃう傾向がありますが、基本的にコンピュータはめんどくさがらないんですよね。だから超めんどくさいことをやらせちゃえば良いのです。やはりプログラマにはちょっとSっ気が必要です。
以下のプログラムは1つのコールジャッジをもとに、すべての正解パタンから当てはまらないものをはじき出すルーチンです。
VOID Analyze :: CandidateByCall( BOOL * buffer, Number maxNumber, const Call & call ) { Call call2; call2.number = call.number; for ( int number = 0; number < maxNumber; number++ ) { if ( buffer[ number ] ) { Judge( number, call2 ); if ( call2.eat != call.eat || call2.byte != call.byte ) { buffer[ number ] = FALSE; } else if ( number == call.number && call.eat != maxColumn ) { buffer[ number ] = FALSE; } } } }
設定桁数が3桁の場合だと0から999まで1000種類の正解パタンがありますが、もちろん000や999など同じ番号が使われてるものは初期化時にはじいてあります。そのデータがbufferです。3桁だと最初は全部で720種類あります。
このアルゴリズムは、与えられたコールジャッジが全正解パタンにマッチするかどうか調査して、マッチしなかったものを正解パタン配列から除外しています。超シンプルだよね。アイテム使用を考慮しなければこれだけで完璧なヌメロン検証プログラムができちゃうよ。やったね!
ちなみにコールジャッジ判定ルーチンは説明するまでも無いほど単純。
typedef LONG Number; typedef LONG Column; typedef DigitID Array[ MAX_COLUMN ]; struct Call { Number number; Column eat; Column byte; }; VOID Numer0n :: Judge( Number number, Call & call ) { Array array; Array array2; NumberToArray( number, array ); NumberToArray( call.number, array2 ); call.eat = 0; call.byte = 0; for ( int column = 0; column < maxColumn; column++ ) { for ( int column2 = 0; column2 < maxColumn; column2++ ) { if ( array2[ column ] == array[ column2 ] ) { if ( column == column2 ) { call.eat++; } else { call.byte++; } } } } }
終了。