△K2△さんも図形問題にはまってしまいましたか。私も今図形問題に取り組んでいますよ。図形問題っていうのは面白いですよね。どこに一本の補助線を引くか、はたまたこの三角形とこの三角形は相似形だからうんぬんと悩みながら、ふと閃く解法で一気に解けた時のなんともいえぬ気持ち、たまらないですね。
実は数ある図形問題の内、どうしても2つ解けないものがあるのです。先日来悩んでいます。イライラがつのるのですが、こと図形問題となるとパソコンもお手上げです。
前置きはこれぐらいにして第4問です。
82391 □▽○◇△ + 19328 + △◇○▽□ --------------- --------------- 101719 163535
これなんかはパソコンなしでも皆さん解けてしまうと思うのですが例の如くコーディングしてみました。今回のプログラムについては2、3述べておきたいことがあります。リストのあとに書いておきました。
/* MSC 5.1 */ #include <stdio.h> #include <stdlib.h> /* 任意の5桁の数の逆さまの数を求める */ long reverse(long n) { unsigned char digit[6]; unsigned int work; sprintf(digit, "%ld", n); /* 数を一旦文字列に変換して入れ換える */ work = digit[0]; digit[0] = digit[4]; digit[4] = work; work = digit[1]; digit[1] = digit[3]; digit[3] = work; return( atol(digit) ); /* 文字列から整数へ変換 */ } main() { long n, r; /* 可能性のある5桁の数すべてについて検査する */ for(n = 10000L; n <= 99999L; n++){ r = reverse( n ); if( (n + r) == 163535L ) printf("Answer: %ld + %ld = 163535 \n", n, r); } }
△K2△さんから私のコーディングに対して指摘がありましたが、おっしゃるように、ただただ問題に忠実にをモットーに行っています。上のプログラムを走らせると、いかな高速パソコンといえどちょっとだんまりとなります。なにしろ for ループのループ回数は約9万回まわります。この問題ではちょっと考えれば n の値は 50000 から調べればいいことが分かります。また、一の位の数に 0 はきませんから検査対象からこういう数は外すといいかも知れません。ですがこういう考察をプログラミングの前に色々やりだしますとプログラムを書くのが遅くなるのとあげくの果てにはプログラミングの必要性もなくなります。おのずと解が見つかってしまうからです。目的は頭のいい小学生にプログラムで勝負しようというわけですからあれこれプログラムをいじくっていては勝てる勝負も勝てなくなります。いかに早くバグのないプログラムを書くかをここでは目標においたわけです。
関数 reverse() のコーディングもいい加減に行っています。プログラミングの学習テーマとしては任意文字列を左、右入れ換えるものを作るのがいいのでしょうが,そんなことをすればいくつかのバグを多分だしてしまうでしょう。この問題では5桁と最初から分かっていますから簡単に入れ換えをしてしまっています。また, sprintf(digit, "%ld", n); の中の "%ld" も n が必ず5桁であることを前提にしてます。
というような次第、堅苦しいこと抜きにプログラミングを楽しめればという目的でやっているのですががこんなつまらぬプログラムでも数をこなせばそれなりに力もつくのではなかろうかと思うのですがいかがでしょうか。
では今回はおまけをつけましょう。次の問題を考えてみてください。どなたかこれをプログラムしてみませんか? 私は遠慮しておきます。なお、この問題の2つめの答については私は正解がだせませんでした。ちょっと時間が足りませんでした。