パズルに挑戦1

ページトップへ 一つ上へ

ポイント


虫食い算



さてさて、今回はパズルに挑戦してみましょう。
パズルというのは人間が考えて解く問題です。
人間ならではというような思考をどのようにしてコンピュータに取り入れるか?
今回はそこが課題になってきます。

さて、人間の思考をコンピュータに。
難しそうに聞こえますが、そんなに難しくはないです。
(非難が聞こえてきそうですが)
まずは、パズルの問題です。

   □□□□□
  ×  □□□
  ――――――
   □4□□□
  □□4□□
 □□□4□
――――――――
1□□□□444

若干ずれてるのは気にしないで下さい。

さて、これを人間にやれと言われても、
解ける人はわずかでしょう(出来ない事はない)
こういう問題だからコンピュータに解かせようってわけです。

ではまず考え方を。
与えられた情報から何が得られるかを考えてみましょう。

まず最初の5桁の数字をaとします。そして、次の3桁の数字をbとします。
bの一の位、十の位、百の位をb0、b1、b2とします。
同様に、1□□□□444をcとして、
□4□□□をc0、□□4□□をc1、□□□4□をc2とする。

ここから考えられる事を列挙していきましょう。

1.aは5桁
2.bは3桁
3.c0=a×b0
4.c1=a×b1
5.c2=a×b2
6.b=b2×100+b1×10+b0
7.c=a×b

8.途中に4があるのでbには0は入らない ここまでは誰でも思いつきますよね。
さて、ここから求めていくための条件が出てきます。

条件1.c0は5桁以下の数で、千の位が4
条件2.c1は4桁以下の数で、百の位が4
条件3.c2は4桁以下の数で、十の位が4
条件4.cは8桁の数で、初めが1、下3桁が444である。

これがこの問題を解くタメの条件になります。

さて、それではプログラムをどうやって書けばいいか、
まずは流れを書いてみましょう。
function quiz1

% 
% 虫食い算解答プログラム
% 擬似プログラミング
% 第一版
%

aが10000〜99999まで繰り返す
 b0が1〜9まで繰り返す
  c0=a×b0
   条件1
    b1が1〜9まで繰り返す
     c1=a×b1
      条件2
       b2が1〜9まで繰り返す
        c2=a×b2
         条件3
          c=c2×100+c1×10+c0
           条件4
            答えが求まる


このような感じになるのはわかるだろうか?
少々わかり難いので、繰り返す部分と計算の部分を
MATLABでプログラミングしてみよう。
function quiz1

% 
% 虫食い算解答プログラム
% 擬似プログラミング
% 第二版
%

for a = 10000 : 99999
 for b0 = 1 : 9
  c0 = a * b0;
   条件1
    for b1 = 1 : 9
     c1=a*b1;
      条件2
       for b2 = 1 : 9
        c2 = a * b2;
         条件3
          c = 100 * c2 + 10 * c1 + c0;
           条件4
            答えが求まる
              end
         end
   end
end


さて、少々わかりやすくなってきた。
あとは条件部分のプログラミングだけだ。
では、一つずつ説明していこう。

まずは、「条件1.c0は5桁以下の数で、千の位が4」

これをどうやってプログラミングするか?
条件なのだから、if文になるのはわかるだろう。
さて、5桁以下というのは、

c0 < 100000


というようになる。cが100000よりも小さい。
これをif文を使って書くと、

if c0 < 100000


というようになる。
またもう一つの条件である、「千の位が4」という部分について。
この千の位というのはどうやって求めるかという事ですが、
千で割った商の下一桁、つまりそれを十で割った余りという事になります。
例えば、12345ならこれを1000で割って12.345になり、これを
十で割った余りは2.345。これを小数点以下切り捨てれば良い。
では、これをどうやって書くか。

c0 / 1000


これが千で割った事になり、さらにそれを十で割った余り。
余りの計算は、

mod(a,b)


で、a/bの余りが求められるので、

mod((c/1000),10)


これで十で割った余りが求まる。そして、これの小数点以下を切り捨てる。

floor(mod((c/1000),10))


これが千の位になる。これが4ならという事は、

floor(mod((c/1000),10))==4


これで、条件は整った。これを先ほどの条件と両方満たせばという事なので、
二つの条件を論理和で結んで、if文にする。

if c<100000 & floor(mod((c/1000,10))==4


これが条件1.になる。同様に条件2,3,4について書いてみると、

if c<100000 & floor(mod((c/100,10))==4


if c<100000 & floor(mod((c/100,10))==4


if floor(c/10000000)==1 & floor(mod(c,1000))==444


という事になるので、さきほどのプログラムを完成させると
function quiz1

% 
% 虫食い算解答プログラム
% 第三版
%

for a = 10000 : 99999
 for b0 = 1 : 9
  c0 = a * b0;
   if c<100000 & floor(mod((c/1000,10))==4
    for b1 = 1 : 9
     c1=a*b1;
      if c<100000 & floor(mod((c/100,10))==4
       for b2 = 1 : 9
        c2 = a * b2;
         if c<100000 & floor(mod((c/100,10))==4
          c = 100 * c2 + 10 * c1 + c0;
           if floor(c/10000000)==1 & floor(mod(c,1000))==444
            fprintf('aは%d bは%d%d%d',a,b2,b1,b0);
                      end
                  end
              end
            end
         end
       end
   end
end


これが答えになる。
ちなみに実行結果はナイショである。
各々これを実行させて解いてみてください。