朝日新聞2005年4月1日パズル横丁解答

プログラムの実行結果は以下の通り。

37c9f0
・・・■■■・
・・・■■□□
・・・■・□□
■■■■■□・
■■□□□□・
・・□□・□・
・・□・・・・
3fc83600
・・・□□□・
・・・□□■■
・・・□・■■
□□□□□■・
□□■■■■・
・・■■・■・
・・■・・・・
time:39.421秒

これを絵にすると以下の通り。

プログラムのソースは以下の通り。やたら長いがやっていることはそう難しいことではない。

#include "puzutl.h"

// □□□012□
// □□□3456
// □□□7□89
// 101112131415□
// 161718192021□
// □□2223□24□
// □□25□□□□

// 0123456
// 78910111213
// 14151617181920
// 21222324252627
// 28293031323334
// 35363738394041
// 42434445464748
  
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;
const ulong bit16 = 0x00010000;
const ulong bit17 = 0x00020000;
const ulong bit18 = 0x00040000;
const ulong bit19 = 0x00080000;
const ulong bit20 = 0x00100000;
const ulong bit21 = 0x00200000;
const ulong bit22 = 0x00400000;
const ulong bit23 = 0x00800000;
const ulong bit24 = 0x01000000;
const ulong bit25 = 0x02000000;
const ulong bit26 = 0x04000000;
const ulong bit27 = 0x08000000;
const ulong bit28 = 0x10000000;
const ulong bit29 = 0x20000000;
const ulong bit30 = 0x40000000;
const ulong bit31 = 0x80000000;
const int64 bit32 = 0x0000000100000000L;
const int64 bit33 = 0x0000000200000000L;
const int64 bit34 = 0x0000000400000000L;
const int64 bit35 = 0x0000000800000000L;
const int64 bit36 = 0x0000001000000000L;
const int64 bit37 = 0x0000002000000000L;
const int64 bit38 = 0x0000004000000000L;
const int64 bit39 = 0x0000008000000000L;
const int64 bit40 = 0x0000010000000000L;
const int64 bit41 = 0x0000020000000000L;
const int64 bit42 = 0x0000040000000000L;
const int64 bit43 = 0x0000080000000000L;
const int64 bit44 = 0x0000100000000000L;
const int64 bit45 = 0x0000200000000000L;
const int64 bit46 = 0x0000400000000000L;
const int64 bit47 = 0x0000800000000000L;
const int64 bit48 = 0x0001000000000000L;
const int64 bit49 = 0x0002000000000000L;
const int64 bit50 = 0x0004000000000000L;
const int64 bit51 = 0x0008000000000000L;
const int64 bit52 = 0x0010000000000000L;
const int64 bit53 = 0x0020000000000000L;
const int64 bit54 = 0x0040000000000000L;
const int64 bit55 = 0x0080000000000000L;
const int64 bit56 = 0x0100000000000000L;
const int64 bit57 = 0x0200000000000000L;
const int64 bit58 = 0x0400000000000000L;
const int64 bit59 = 0x0800000000000000L;
const int64 bit60 = 0x1000000000000000L;
const int64 bit61 = 0x2000000000000000L;
const int64 bit62 = 0x4000000000000000L;
const int64 bit63 = 0x8000000000000000L;

const ulong bits[] = {bit0,bit1,bit2,bit3,bit4,bit5,bit6,bit7,bit8,bit9,bit10,bit11,bit12,bit13,bit14,bit15,bit16,bit17,bit18,bit19,bit20,bit21,bit22,bit23,bit24,bit25,bit26};

void neighborOff( ulong& n, ulong bit)
{
  //dumpblock( n);
  if     ( bit0  & n & bit) {n &= ~bit0;  neighborOff( n, bit1);  neighborOff( n, bit3); }
  else if( bit1  & n & bit) {n &= ~bit1;  neighborOff( n, bit0);  neighborOff( n, bit2);  neighborOff( n, bit4); }
  else if( bit2  & n & bit) {n &= ~bit2;  neighborOff( n, bit1);  neighborOff( n, bit5); }
  else if( bit3  & n & bit) {n &= ~bit3;  neighborOff( n, bit0);  neighborOff( n, bit4);  neighborOff( n, bit7); }
  else if( bit4  & n & bit) {n &= ~bit4;  neighborOff( n, bit1);  neighborOff( n, bit3);  neighborOff( n, bit5); }
  else if( bit5  & n & bit) {n &= ~bit5;  neighborOff( n, bit2);  neighborOff( n, bit4);  neighborOff( n, bit6);  neighborOff( n, bit8);}
  else if( bit6  & n & bit) {n &= ~bit6;  neighborOff( n, bit5);  neighborOff( n, bit9); }
  else if( bit7  & n & bit) {n &= ~bit7;  neighborOff( n, bit3);  neighborOff( n, bit13); }
  else if( bit8  & n & bit) {n &= ~bit8;  neighborOff( n, bit5);  neighborOff( n, bit9);  neighborOff( n, bit15); }
  else if( bit9  & n & bit) {n &= ~bit9;  neighborOff( n, bit6);  neighborOff( n, bit8); }
  else if( bit10 & n & bit) {n &= ~bit10; neighborOff( n, bit11);  neighborOff( n, bit16); }
  else if( bit11 & n & bit) {n &= ~bit11; neighborOff( n, bit10);  neighborOff( n, bit12);  neighborOff( n, bit17); }
  else if( bit12 & n & bit) {n &= ~bit12; neighborOff( n, bit11);  neighborOff( n, bit13);  neighborOff( n, bit18); }
  else if( bit13 & n & bit) {n &= ~bit13; neighborOff( n, bit7);  neighborOff( n, bit12);  neighborOff( n, bit14); neighborOff( n, bit19); }
  else if( bit14 & n & bit) {n &= ~bit14; neighborOff( n, bit13);  neighborOff( n, bit15);  neighborOff( n, bit20); }
  else if( bit15 & n & bit) {n &= ~bit15; neighborOff( n, bit8);  neighborOff( n, bit14);  neighborOff( n, bit21); }
  else if( bit16 & n & bit) {n &= ~bit16; neighborOff( n, bit10); neighborOff( n, bit17); }
  else if( bit17 & n & bit) {n &= ~bit17; neighborOff( n, bit11); neighborOff( n, bit16);  neighborOff( n, bit18); }
  else if( bit18 & n & bit) {n &= ~bit18; neighborOff( n, bit12); neighborOff( n, bit17);  neighborOff( n, bit19); neighborOff( n, bit22); }
  else if( bit19 & n & bit) {n &= ~bit19; neighborOff( n, bit13); neighborOff( n, bit18);  neighborOff( n, bit20); neighborOff( n, bit23); }
  else if( bit20 & n & bit) {n &= ~bit20; neighborOff( n, bit14); neighborOff( n, bit19);  neighborOff( n, bit21); }
  else if( bit21 & n & bit) {n &= ~bit21; neighborOff( n, bit15); neighborOff( n, bit20);  neighborOff( n, bit24); }
  else if( bit22 & n & bit) {n &= ~bit22; neighborOff( n, bit18); neighborOff( n, bit23);  neighborOff( n, bit25); }
  else if( bit23 & n & bit) {n &= ~bit23; neighborOff( n, bit19); neighborOff( n, bit22); }
  else if( bit24 & n & bit) {n &= ~bit24; neighborOff( n, bit21); }
  else if( bit25 & n & bit) {n &= ~bit25; neighborOff( n, bit22); }
}

YesNo contcheck( ulong n)
{
  //--------------------------------------------------------------------
  // パーツが連続しているかどうか調べる。
  // YES:連続している。
  // NO :連続していない。
  // 最初に見つかったビットに隣接するビットを削除していって戻ってきたとき,
  // 削除されていないビットがあれば連続していない。削除されていないビットがなければ連続している。
  //--------------------------------------------------------------------
  for( int i=0; i< 26; i++) {
    if( bits[i] & n) {
      neighborOff( n, bits[i]);
      n &= ~bits[i];
      return    n?NO:YES;
    }
  }
  return    NO;
}

void dumpblock( int x)
{
  ps( "%x\n", x);
  ps( "・");
  ps( "・");
  ps( "・");
  if( x & bit0) ps( "■"); else ps( "□");
  if( x & bit1) ps( "■"); else ps( "□");
  if( x & bit2) ps( "■"); else ps( "□");
  ps( "・"); ps( "\n");
  ps( "・");
  ps( "・");
  ps( "・");
  if( x & bit3) ps( "■"); else ps( "□");
  if( x & bit4) ps( "■"); else ps( "□");
  if( x & bit5) ps( "■"); else ps( "□");
  if( x & bit6) ps( "■"); else ps( "□");
  ps( "\n");
  ps( "・");
  ps( "・");
  ps( "・");
  if( x & bit7) ps( "■"); else ps( "□");
  ps( "・");
  if( x & bit8) ps( "■"); else ps( "□");
  if( x & bit9) ps( "■"); else ps( "□");
  ps( "\n");
  if( x & bit10) ps( "■"); else ps( "□");
  if( x & bit11) ps( "■"); else ps( "□");
  if( x & bit12) ps( "■"); else ps( "□");
  if( x & bit13) ps( "■"); else ps( "□");
  if( x & bit14) ps( "■"); else ps( "□");
  if( x & bit15) ps( "■"); else ps( "□");
  ps( "・");
  ps( "\n");
  if( x & bit16) ps( "■"); else ps( "□");
  if( x & bit17) ps( "■"); else ps( "□");
  if( x & bit18) ps( "■"); else ps( "□");
  if( x & bit19) ps( "■"); else ps( "□");
  if( x & bit20) ps( "■"); else ps( "□");
  if( x & bit21) ps( "■"); else ps( "□");
  ps( "・");
  ps( "\n");
  ps( "・");
  ps( "・");
  if( x & bit22) ps( "■"); else ps( "□");
  if( x & bit23) ps( "■"); else ps( "□");
  ps( "・");
  if( x & bit24) ps( "■"); else ps( "□");
  ps( "・");
  ps( "\n");
  ps( "・");
  ps( "・");
  if( x & bit25) ps( "■"); else ps( "□");
  ps( "・");
  ps( "・");
  ps( "・");
  ps( "・"); ps( "\n");
}

int64 conv64( ulong x) {
  int64         v = 0;
  if( x&bit0 ) v|= bit3;
  if( x&bit1 ) v|= bit4;
  if( x&bit2 ) v|= bit5;
  if( x&bit3 ) v|= bit10;
  if( x&bit4 ) v|= bit11;
  if( x&bit5 ) v|= bit12;
  if( x&bit6 ) v|= bit13;
  if( x&bit7 ) v|= bit17;
  if( x&bit8 ) v|= bit19;
  if( x&bit9 ) v|= bit20;
  if( x&bit10) v|= bit21;
  if( x&bit11) v|= bit22;
  if( x&bit12) v|= bit23;
  if( x&bit13) v|= bit24;
  if( x&bit14) v|= bit25;
  if( x&bit15) v|= bit26;
  if( x&bit16) v|= bit28;
  if( x&bit17) v|= bit29;
  if( x&bit18) v|= bit30;
  if( x&bit19) v|= bit31;
  if( x&bit20) v|= bit32;
  if( x&bit21) v|= bit33;
  if( x&bit22) v|= bit37;
  if( x&bit23) v|= bit38;
  if( x&bit24) v|= bit40;
  if( x&bit25) v|= bit44;
  return    v;
}
int64 rotate90( int64 x) {
  int64 v = 0;
  if( x&bit0) v |= bit42;
  if( x&bit1) v |= bit35;
  if( x&bit2) v |= bit28;
  if( x&bit3) v |= bit21;
  if( x&bit4) v |= bit14;
  if( x&bit5) v |= bit7;
  if( x&bit6) v |= bit0;
  if( x&bit7) v |= bit43;
  if( x&bit8) v |= bit36;
  if( x&bit9) v |= bit29;
  if( x&bit10) v |= bit22;
  if( x&bit11) v |= bit15;
  if( x&bit12) v |= bit8;
  if( x&bit13) v |= bit1;
  if( x&bit14) v |= bit44;
  if( x&bit15) v |= bit37;
  if( x&bit16) v |= bit30;
  if( x&bit17) v |= bit23;
  if( x&bit18) v |= bit16;
  if( x&bit19) v |= bit9;
  if( x&bit20) v |= bit2;
  if( x&bit21) v |= bit45;
  if( x&bit22) v |= bit38;
  if( x&bit23) v |= bit31;
  if( x&bit24) v |= bit24;
  if( x&bit25) v |= bit17;
  if( x&bit26) v |= bit10;
  if( x&bit27) v |= bit3;
  if( x&bit28) v |= bit46;
  if( x&bit29) v |= bit39;
  if( x&bit30) v |= bit32;
  if( x&bit31) v |= bit25;
  if( x&bit32) v |= bit18;
  if( x&bit33) v |= bit11;
  if( x&bit34) v |= bit4;
  if( x&bit35) v |= bit47;
  if( x&bit36) v |= bit40;
  if( x&bit37) v |= bit33;
  if( x&bit38) v |= bit26;
  if( x&bit39) v |= bit19;
  if( x&bit40) v |= bit12;
  if( x&bit41) v |= bit5;
  if( x&bit42) v |= bit48;
  if( x&bit43) v |= bit41;
  if( x&bit44) v |= bit34;
  if( x&bit45) v |= bit27;
  if( x&bit46) v |= bit20;
  if( x&bit47) v |= bit13;
  if( x&bit48) v |= bit6;
  return v;
}
int64 reverse( int64 x) {
  int64 v = 0;
  if( x&bit0) v |= bit6;
  if( x&bit1) v |= bit5;
  if( x&bit2) v |= bit4;
  if( x&bit3) v |= bit3;
  if( x&bit4) v |= bit2;
  if( x&bit5) v |= bit1;
  if( x&bit6) v |= bit0;
  if( x&bit7) v |= bit13;
  if( x&bit8) v |= bit12;
  if( x&bit9) v |= bit11;
  if( x&bit10) v |= bit10;
  if( x&bit11) v |= bit9;
  if( x&bit12) v |= bit8;
  if( x&bit13) v |= bit7;
  if( x&bit14) v |= bit20;
  if( x&bit15) v |= bit19;
  if( x&bit16) v |= bit18;
  if( x&bit17) v |= bit17;
  if( x&bit18) v |= bit16;
  if( x&bit19) v |= bit15;
  if( x&bit20) v |= bit14;
  if( x&bit21) v |= bit27;
  if( x&bit22) v |= bit26;
  if( x&bit23) v |= bit25;
  if( x&bit24) v |= bit24;
  if( x&bit25) v |= bit23;
  if( x&bit26) v |= bit22;
  if( x&bit27) v |= bit21;
  if( x&bit28) v |= bit34;
  if( x&bit29) v |= bit33;
  if( x&bit30) v |= bit32;
  if( x&bit31) v |= bit31;
  if( x&bit32) v |= bit30;
  if( x&bit33) v |= bit29;
  if( x&bit34) v |= bit28;
  if( x&bit35) v |= bit41;
  if( x&bit36) v |= bit40;
  if( x&bit37) v |= bit39;
  if( x&bit38) v |= bit38;
  if( x&bit39) v |= bit37;
  if( x&bit40) v |= bit36;
  if( x&bit41) v |= bit35;
  if( x&bit42) v |= bit48;
  if( x&bit43) v |= bit47;
  if( x&bit44) v |= bit46;
  if( x&bit45) v |= bit45;
  if( x&bit46) v |= bit44;
  if( x&bit47) v |= bit43;
  if( x&bit48) v |= bit42;
  return    v;
}
int64 normalize( int64 x) {
  int64 v = 0;

  while( !(x & (bit0|bit1|bit2|bit3|bit4|bit5|bit6))) {
    x >>= 7;
  }
  while( !(x & (bit0|bit7|bit14|bit21|bit28|bit35|bit42))) {
    x = ((x&(bit1|bit2|bit3|bit4|bit5|bit6))>>1)
      | ((x&(bit8|bit9|bit10|bit11|bit12|bit13))>>1)
      | ((x&(bit15|bit16|bit17|bit18|bit19|bit20))>>1)
      | ((x&(bit22|bit23|bit24|bit25|bit26|bit27))>>1)
      | ((x&(bit29|bit30|bit31|bit32|bit33|bit34))>>1)
      | ((x&(bit36|bit37|bit38|bit39|bit40|bit41))>>1)
      | ((x&(bit43|bit44|bit45|bit46|bit47|bit48))>>1)
;
  }
  return    x;
}
void dump64( int64 x) {
  ps( "--------------------------------------------------\n");
  for( int row=0; row< 7; row++) {
    for( int col=0; col< 7; col++) {
      if( x&1) ps( "■");
      else     ps( "□");
      x >>= 1;
    }
    ps( "\n");
  }
}
int main( int argc, cstring argv[])
{
  ProcTime      pt;
  for( int i=0; i< 0x3FFFFFF; i++) {
    if( i%100000 == 0) ps( "%d\r", i);
    if( bitcount(i) == 13 && contcheck(i) && contcheck(~i&0x3FFFFFF)) {
      // これを64ビットに変換する。
      int64 black = conv64(i);
      int64 white = conv64(~i&0x3FFFFFF);
      // 正規化する。
      int64 pat0 = normalize(black);
      int64 d1 = white;
      int64 d2 = rotate90(d1);
      int64 d3 = rotate90(d2);
      int64 d4 = rotate90(d3);
      int64 r1 = reverse(d1);
      int64 r2 = rotate90(r1);
      int64 r3 = rotate90(r2);
      int64 r4 = rotate90(r3);
      int64 data[] = { normalize(d1), normalize(d2), normalize(d3), normalize(d4), normalize(r1), normalize(r2), normalize(r3), normalize(r4)};
      for( int j=0; j< 8; j++) {
        if( data[j] == pat0) {
          dumpblock( i);
        }
      }
    }
  }
  pt.end();
  ps( "time:%g秒\n", pt.sec());
  return    0;
}