プログラムの実行結果は以下の通り。
8 1 2 8 1 2 8 1 2 7 9 3 7 9 3 7 9 3 6 5 4 6 5 4 6 5 4 8 1 2 8 1 2 8 1 2 7 9 3 7 9 3 7 9 3 6 5 4 6 5 4 6 5 4 8 1 2 8 1 2 8 1 2 7 9 3 7 9 3 7 9 3 6 5 4 6 5 4 6 5 4 FIND
但し答えはこれだけでなく沢山ある。出題意図がよく判らない。
真ん中の数字は9になり他の数字にはならないので,「真ん中の数字は何か?」が本当の出題意図なのかもしれない。
プログラムのソースは以下の通り。
#include "puzutl.h" int mat[9][9]; YesNo ynFind = YES; // 解が見つかった? void pad( int irow, int icol, int val) { if( irow < 0 || irow >= 9) return; // 範囲外 if( icol < 0 || icol >= 9) return; if(!(mat[irow][icol]==0||mat[irow][icol]==val)) { // 既に値が設定されていて,設定しようとする値と異なれば問題あり pe( "ERROR [%d][%d] : %d => %d\n", irow, icol, mat[irow][icol], val); ynFind = NO; } if( mat[irow][icol]) return; // 既に値が設定されている場所 mat[irow][icol] = val; // 新しい値を設定する。 pad( irow+3, icol+0, mat[irow][icol]); // 3つ右に同じ値を設定する。 pad( irow-3, icol+0, mat[irow][icol]); // 3つ左に同じ値を設定する。 pad( irow+0, icol+3, mat[irow][icol]); // 3つ下に同じ値を設定する。 pad( irow+0, icol-3, mat[irow][icol]); // 3つ上に同じ値を設定する。 } void pad_start( int irow, int icol) { pad( irow+3, icol+0, mat[irow][icol]); pad( irow-3, icol+0, mat[irow][icol]); pad( irow+0, icol+3, mat[irow][icol]); pad( irow+0, icol-3, mat[irow][icol]); } YesNo check( int irow, int icol) // 3x3が正しいか? { int twice[9+1] = {0}; for( int row=0; row< 3; row++) { for( int col=0; col< 3; col++) { if( ++twice[mat[irow+row][icol+col]] > 1) return NO; } } return YES; } int main( int argc, cstring argv[]) { // 初期状態を設定する。 mat[0][0] = 8; mat[4][0] = 7; mat[8][0] = 6; mat[0][4] = 1; mat[0][8] = 2; mat[4][8] = 3; mat[8][4] = 5; mat[8][8] = 4; // 3個先を同じ数字で埋める。 pad_start( 0, 0); pad_start( 4, 0); pad_start( 8, 0); pad_start( 0, 4); pad_start( 0, 8); pad_start( 4, 8); pad_start( 8, 4); pad_start( 8, 8); // 最初の3x3に9を設定できる所を探し,見つかれば同じ処理で9を埋める。 int irow, icol; for( irow=0; irow< 3; irow++) { for( icol=0; icol< 3; icol++) { if( mat[irow][icol] == 0) { mat[irow][icol] = 9; pad_start(irow,icol); } } } if( !ynFind) return 0; // 既にエラーがあればダメ。 // 現在の設定値を出力してみる。 for( irow=0; irow< 9; irow++) { for( icol=0; icol< 9; icol++) { ps( "%d ", mat[irow][icol]); if( mat[irow][icol] == 0) ynFind = NO; } ps( "\n"); } // 念のため全ての3x3をチェックする for( irow=0; irow< 6; irow++) { for( icol=0; icol< 6; icol++) { if( !check( irow, icol)) ynFind = NO; } } if( ynFind) ps( "FIND\n"); return 0; }