パソコンの計算能力を試してみようと中古で買ったCeleron 2.6GHzのデスクトップPCで掲載画像のような覆面算を解かせてみた。3年くらい前の機種なので10秒くらいはかかるのかと予想したが、なんと0.13秒で解けてしまった。
この覆面算はそれぞれの英文字のところに0~9の数字をあてはめて足し算が成り立つようにするものだ。英文字が異なれば違う数字とし、各行の一番大きい桁のUとPはゼロではない。この条件でプログラムをLinux上のC言語で組み、可能な約48万パターンを順番に試したわけである。
スピードの実感がわかなかったので同じプログラムを1000回まわしたところ2分10秒かかった。約4億8千万パターン試したことに等しい。かなりのスピードだ。。。(画面出力のためのprintfコマンドは実行時間がかかるのでスキップさせて計算した。)
1982年に僕がはじめて手にした富士通パソコン「初代FM-7」のCPUのクロック数は8MHzだった。当時、本体は12万6千円で14インチカラーモニターは15万円ほどだった。プリンタと合わせて総額46万円だったのを覚えている。(簡単に親にねだって買ってもらったこと、当時の父の月給のことを思うと世間知らずで理屈ばかりこねていた自分がとても恥ずかしい。親孝行しなきゃな。。。)ともかくクロック数だけでくらべると親のすねかじりパソコンの計算速度は現在の332分の1なわけで、この覆面算を解かせるのに43秒くらいかかっていたはずだ。
計算速度だけ取り上げるのはいささか幼稚な気もするが、物理シミュレーションやフラクタル図形の描画、癌の治療薬研究プロジェクトは計算速度の圧倒的な向上によって可能になったことを忘れてはならない。現在でもパソコンによる世界的規模のさまざまな計算プロジェクトが進行中である。
以下が覆面算の計算結果とそのプログラムだ。アルゴリズムを工夫すれば多少早くなるが、大勢に影響はないだろう。
計算結果:
U=9 S=3 A=2 R=8 P=1 E=0 C=7
932
+ 9338
------
10270
プログラム:
// fukumenzan.c
#include <stdio.h>
int main(void)
{
int u, s, a, r, p, e, c;
int usa, ussr, peace;
u = s = a = r = p = e = c = 0;
for (u=1;u<10;u++) {
for (s=0;s<10;s++) {
for (a=0;a<10;a++) {
for (r=0;r<10;r++) {
for (p=1;p<10;p++) {
for (e=0;e<10;e++) {
for (c=0;c<10;c++) {
if (u==s || u==a || u==r || u==p || u==e || u==c) continue;
if (s==u || s==a || s==r || s==p || s==e || s==c) continue;
if (a==s || a==u || a==r || a==p || a==e || a==c) continue;
if (r==s || r==a || r==u || r==p || r==e || r==c) continue;
if (p==s || p==a || p==r || p==u || p==e || p==c) continue;
if (e==s || e==a || e==r || e==p || e==u || e==c) continue;
if (c==s || c==a || c==r || c==p || c==e || c==u) continue;
usa = 100*u + 10*s + a;
ussr = 1000*u + 100*s + 10*s + r;
peace = 10000*p + 1000*e + 100*a + 10*c + e;
if (usa + ussr == peace) {
printf("U=%d S=%d A=%d R=%d P=%d E=%d C=%d\n\n"
,u,s,a,r,p,e,c);
printf(" %d%d%d\n",u,s,a);
printf("+ %d%d%d%d\n",u,s,s,r);
printf("------\n");
printf(" %d%d%d%d%d\n",p,e,a,c,e);
}
}}}}}}}
}
はい、この問題の場合、解は一組だけです。
>英文字が異なれば違う数字とし
を 読み飛ばして おりました。
しかし ↓達 も 許容願いたいのは 私だけで しょうか?
{{U -> 9, S -> 1, A -> 0, R -> 0, P -> 1, e -> 0, C -> 2},
{U -> 9, S -> 2, A -> 1, R -> 9, P -> 1, e -> 0, C -> 5},
{U -> 9, S -> 3, A -> 2, R -> 8, P -> 1, e -> 0, C -> 7},
{U -> 9, S -> 4, A -> 3, R -> 7, P -> 1, e -> 0, C -> 9},
{U -> 9, S -> 5, A -> 5, R -> 5, P -> 1, e -> 0, C -> 1},
{U -> 9, S -> 6, A -> 6, R -> 4, P -> 1, e -> 0, C -> 3},
{U -> 9, S -> 7, A -> 7, R -> 3, P -> 1, e -> 0, C -> 5},
{U -> 9, S -> 8, A -> 8, R -> 2, P -> 1, e -> 0, C -> 7},
{U -> 9, S -> 9, A -> 9, R -> 1, P -> 1, e -> 0, C -> 9}}
此処までなら 0 秒で済みます....
(このなかで 英文字が異なれば違う数字 なる条件を満たすのを 拾う手間が余計でもありますし)
ーーーーーーーーーーーーーーーーー
http://event.yomiuri.co.jp/2013/science_57th/works/works_prize49.htm
とありました。
マイクロソフト賞
「覆面算作成機」
東京都・筑波大学附属駒場高校2年 吉里 幸太
http://www.jssa.net/2005/winners49.php
に ↓ が 提起されています;
行儀良い覆面算 投稿者:GAI 投稿日:2016年 3月18日(金)07時33分57秒 返信・引用
RSTUV
SSTUV
TTTUV
UUUUV
+ VVVVV
--------
XXYYZZ
を解くと?
記事で紹介した例は「英文字と数字が1対1」という制限がつきます。
この制限を取り除けば、★様が例示されたものも解になりますね。
「覆面算作成機」や「行儀良い覆面算」のページを紹介いただき、ありがとうございました。