以下の計算式が成り立つように「こ」,「う」,「ん」に0〜9の別々の数字を割り当てる。
3週連続の数字の割り当て問題。数字の数は3種類あるが,「こ」は「う」,「ん」に依存して決まるために実質2種類の数字割り当て問題になる。
数字の割り当て問題と見ないで,「うん」を00から99までの数字と見なして虱潰す方法も考えられる。
[方法1]数字の割り当て問題を利用し,「う」にaを,「ん」にbを対応して考える。「こううん」は(a*10+b)*(a*10+b) になる。
for( int a=0; a< 10; a++) { used[a] = YES; for( int b=0; b< 10; b++) { if( used[b]) continue; used[b] = YES; int x = (a*10 + b) * (a*10+b); int x1 = x % 10; x /= 10; int x2 = x % 10; x /= 10; int x3 = x % 10; x /= 10; int x4 = x % 10; x /= 10; if( 「う」⇒a,「ん」⇒b,「こ」⇒x4,「う」⇒x3,「う」⇒x2,「ん」⇒x1 が成り立つか?) { ps( " %-.2s%-.2s\n", ns+a*2, ns+b*2); ps( "× %-.2s%-.2s\n", ns+a*2, ns+b*2); ps( "----------\n"); ps( "%-.2s%-.2s%-.2s%-.2s\n", ns+x4*2, ns+x3*2, ns+x2*2, ns+x1*2); } used[b] = NO; } used[a] = NO; }
[方法2]00〜99まで全ての数について,二乗を計算し,計算結果が条件を満たすか調べる。
for( int i=0; i< 100; i++) { int j = i; int x = i*i; int x1 = x % 10; x /= 10; int x2 = x % 10; x /= 10; int x3 = x % 10; x /= 10; int x4 = x % 10; x /= 10; int i1 = j % 10; j /= 10; int i2 = j % 10; j /= 10; if( 「う」⇒i2,「ん」⇒i1,「こ」⇒x4,「う」⇒x3,「う」⇒x2,「ん」⇒x1 が成り立つか?) { ps( " %-.2s%-.2s\n", ns+i2*2, ns+i1*2); ps( "× %-.2s%-.2s\n", ns+i2*2, ns+i1*2); ps( "----------\n"); ps( "%-.2s%-.2s%-.2s%-.2s\n", ns+x4*2, ns+x3*2, ns+x2*2, ns+x1*2); } }
答えを全角で出力するように以下のように設定する。
cstring ns = "0123456789";
方法1,方法2とも1件出力されました。
解速度
即