以下の図で直線上の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に変換する。
私には考えられないけど,カット&ペーストもマウスって人も結構いるみたいだ。
解速度
即