プログラムの実行結果は以下の通り。
××□□ ×□□□ □□□● □□●□
プログラムのソースは以下の通り。
#include "puzutl.h" const ulong bit0 = 0x00000001; const ulong bit1 = 0x00000002; const ulong bit2 = 0x00000004; const ulong bit3 = 0x00000008; const ulong bit4 = 0x00000010; const ulong bit5 = 0x00000020; const ulong bit6 = 0x00000040; const ulong bit7 = 0x00000080; const ulong bit8 = 0x00000100; const ulong bit9 = 0x00000200; const ulong bit10 = 0x00000400; const ulong bit11 = 0x00000800; const ulong bit12 = 0x00001000; const ulong bit13 = 0x00002000; const ulong bit14 = 0x00004000; const ulong bit15 = 0x00008000; int shiftZukei( int z, YesNo yn_dirx, YesNo yn_diry) // 4x4の図形を移動する上下左右に移動する { // +--+--+--+--+ // |A|B|C|D| // +--+--+--+--+ // |E|F|G|H| // +--+--+--+--+ // |I|J|K|L| // +--+--+--+--+ // |M|N|O|P| // +--+--+--+--+ if( yn_dirx) { // 横方向に移動する // +--+--+--+--+ // | |A|B|C| // +--+--+--+--+ // | |E|F|G| // +--+--+--+--+ // | |I|J|K| // +--+--+--+--+ // | |M|N|O| // +--+--+--+--+ if( z & (bit3|bit7|bit11|bit15)) return 0; // NG(D,H,L,Pに1が立っていれば移動後溢れる) int newZ = 0; if( z & bit0 ) newZ |= bit1; if( z & bit1 ) newZ |= bit2; if( z & bit2 ) newZ |= bit3; if( z & bit4 ) newZ |= bit5; if( z & bit5 ) newZ |= bit6; if( z & bit6 ) newZ |= bit7; if( z & bit8 ) newZ |= bit9; if( z & bit9 ) newZ |= bit10; if( z & bit10) newZ |= bit11; if( z & bit12) newZ |= bit13; if( z & bit13) newZ |= bit14; if( z & bit14) newZ |= bit15; z = newZ; } if( yn_diry) { // +--+--+--+--+ // | | | | | // +--+--+--+--+ // |A|B|C|D| // +--+--+--+--+ // |E|F|G|H| // +--+--+--+--+ // |I|J|K|L| // +--+--+--+--+ if( z & (bit12|bit13|bit14|bit15)) return 0; // NG(M,N,O,Pに1が立っていれば移動後溢れる) int newZ = 0; if( z & bit0 ) newZ |= bit4; if( z & bit1 ) newZ |= bit5; if( z & bit2 ) newZ |= bit6; if( z & bit3 ) newZ |= bit7; if( z & bit4 ) newZ |= bit8; if( z & bit5 ) newZ |= bit9; if( z & bit6 ) newZ |= bit10; if( z & bit7 ) newZ |= bit11; if( z & bit8 ) newZ |= bit12; if( z & bit9 ) newZ |= bit13; if( z & bit10) newZ |= bit14; if( z & bit11) newZ |= bit15; z = newZ; } return z; } int calcAllZ( int z[], int n, int zukei) // 「コの字」の配置方法を求める { int saveZukei = zukei; // 4x4内で基本図形をずらして配置できるものを選ぶ for( int ix=0; ix< 3; ix++) { // X方向にずらす zukei = saveZukei; for( int iy=0; iy< 3; iy++) { // Y方向にずらす if( zukei) { // ずらしても4x4内に図形が存在する if( !(zukei & 0x0013)) { // 左上の欠けている部分に重なっている場合はダメ z[n++] = zukei; // そうでなければ配置できる } } else { break; } zukei = shiftZukei( zukei, NO, YES); // Y方向にずらす } saveZukei = shiftZukei( saveZukei, YES, NO); // X方向にずらす } return n; } void print_find( int i) { if( i & bit0 ) ps( "●"); else ps( "×"); if( i & bit1 ) ps( "●"); else ps( "×"); if( i & bit2 ) ps( "●"); else ps( "□"); if( i & bit3 ) ps( "●"); else ps( "□"); ps( "\n"); if( i & bit4 ) ps( "●"); else ps( "×"); if( i & bit5 ) ps( "●"); else ps( "□"); if( i & bit6 ) ps( "●"); else ps( "□"); if( i & bit7 ) ps( "●"); else ps( "□"); ps( "\n"); if( i & bit8 ) ps( "●"); else ps( "□"); if( i & bit9 ) ps( "●"); else ps( "□"); if( i & bit10) ps( "●"); else ps( "□"); if( i & bit11) ps( "●"); else ps( "□"); ps( "\n"); if( i & bit12) ps( "●"); else ps( "□"); if( i & bit13) ps( "●"); else ps( "□"); if( i & bit14) ps( "●"); else ps( "□"); if( i & bit15) ps( "●"); else ps( "□"); ps( "\n"); } int main( int argc, cstring argv[]) { // まず「コの字」の配置を全て求めておく。 int N = 0; // 「コの字」の置き方の総数 const int S = 100; int z[S+1] = {0}; // 「コの字」のビット表現 N = calcAllZ( z, N, 0x0057); // 「コの字」の置き方-1 N = calcAllZ( z, N, 0x0313); // 「コの字」の置き方-2 N = calcAllZ( z, N, 0x0075); // 「コの字」の置き方-3 N = calcAllZ( z, N, 0x0323); // 「コの字」の置き方-4 // 16升の中から2点を選択して,図形の全ての可能性と比較する。 for( int i=0; i< 0x10000; i++) { if( !(i&0x0013) && // 0x0013 は元の図形の欠けている場所 bitcount(i) == 2) { // ビット数が2ということが2点に相当する // 16マスの中から2点を選択した // 全ての組み合わせと重なり合うか調べる。 YesNo yn_find = YES; for( int j=0; j< N; j++) { if( !(i & z[j])) { // 重なりが無い yn_find = NO; break; } } if( yn_find) { print_find( i); } } } return 0; }