朝日新聞2007年3月2日のパズル横丁問題

問題

以下の図で直線上の3つの数字の合計が19になるように○に0〜9の数字を割り当てる。

解答への道(ヒント)

丸の数は8個。そこに0〜9の数字10個を割り当てるので2個余る。最初1〜9だと思ったら0〜9だった。

結果には影響しないけど,ちゃんと仕様通りにプログラムを作らないといけない。

以下のように記号を振ると数字の割り当て問題になる。

直線上の3つの数字の組み合わせは以下の5種類。

a+b+c
a+d+h
c+d+f
c+e+h
f+g+h

3つの引数を足して19になるかどうか判定する関数を作りループの真ん中に判定文を入れれば完成。

#include "puzutl.h"

YesNo sum19( int a, int b, int c)
{
 … a+b+c が19ならYES,そうでなければNOを返す。
}

YesNo used[10];

int main( int argc, cstring argv[])
{
  for( int a=0; a< 10; a++) {
    used[a] = YES;
    for( int b=0; b< 10; b++) {
      if( used[b]) continue;
      used[b] = YES;
      for( int c=0; c< 10; c++) {
        if( used[c]) continue;
        used[c] = YES;
        for( int d=0; d< 10; d++) {
          if( used[d]) continue;
          used[d] = YES;
          for( int e=0; e< 10; e++) {
            if( used[e]) continue;
            used[e] = YES;
            for( int f=0; f< 10; f++) {
              if( used[f]) continue;
              used[f] = YES;
              for( int g=0; g< 10; g++) {
                if( used[g]) continue;
                used[g] = YES;
                for( int h=0; h< 10; h++) {
                  if( used[h]) continue;
                  used[h] = YES;
                  if( sum19(a,b,c) &&
                      sum19(a,d,h) && 
                      sum19(c,d,f) && 
                      sum19(c,e,h) && 
                      sum19(f,g,h)) {
                    … Find
                  }
                  used[h] = NO;
                }
                used[g] = NO;
              }
              used[f] = NO;
            }
            used[e] = NO;
          }
          used[d] = NO;
        }
        used[c] = NO;
      }
      used[b] = NO;
    }
    used[a] = NO;
  }
  return    0;
}

答えは2件出力されました。しかし,a,b,c と f,g,h が入れ替わったものなので実質1件。

重複を除去したければ,以下のようにSTLを使ってabcとfghを入れ替えた答えを判別出来るようにする。

set<string>   finded;
………
if( 見つかった) {
  char    buf[128];
  sprintf( buf, "%d,%d,%d,%d,%d,%d,%d,%d", a, b, c, d, e, f, g, h);
  if( finded.find(buf) == finded.end()) {
    a,b,c,d,e,f,g,hの組み合わせは重複の無い解
    finded.insert(buf);
    sprintf( buf, "%d,%d,%d,%d,%d,%d,%d,%d", f, g, h, d, e, a, b, c); // abcとfghを入れ替えて鏡像を除去
    finded.insert(buf);
  }
}

重複除去した結果1件出力されました。

 

姉と姪はローマ字仮名変換でなく片仮名をダイレクト入力していた。ビックリした。

私は昔片仮名のブラインドタッチを覚えたが,プログラマはやはりアルファベットの入力が多く,効率が上がらないので直ぐに忘れた。

ボーグ(Borg)じゃないけど,プログラマは効率優先

もしかして入力モードが「ひらがな」の時,一時的に半角英数字を入力する私のやり方は少数派か?

例えばincludeの入力は「いんcぅで」を入力後,「^P^O」でincludeに変換する。

私には考えられないけど,カット&ペーストもマウスって人も結構いるみたいだ。

解速度