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