わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

ABCD×9=DCBA

 いきなりですが問題です.

A,B,C,Dはいずれも0以上9以下の整数で,それぞれ異なるものとします.また「ABCD」と書いて,4桁の整数を表します(最上位桁は,0でないとします).
ABCD×9=DCBAを満たすA,B,C,Dを求めなさい.

 元ネタです.

 小学生でも求めることのできる,覆面算の一つです.元ネタには筋道がきちんと書かれていますが,ABCDの4桁に限らず任意桁にしても,そしてかける数を2以上9以下の整数に範囲を広げても,計算機ですべての解を出してくれそうだなと考えまして,Rubyで書きました.ソースファイル(fukumen.rb)は以下のとおりです.

#!/usr/bin/env ruby

digit = (ARGV.shift || 4).to_i

2.upto(9) do |q|
  min = 10 ** (digit - 1)
  max = 10 ** digit - 1
  min.upto(max) do |p|
    a = p.to_s.chars.map { |c| c.to_i }
    next if a.length > a.uniq.length
    product = p * q
    p_rev = a.reverse.join.to_i
    if product == p_rev
      puts "%d * %d = %d" % [p, q, product]
    end
  end
end

 プログラムの解説をします.変数qがかける数(2から9まで),変数pがかけられる数(digitが4のとき,1000から9999まで)です.「a = 」から始まる行は,変数pが保持する整数値を,1桁ごとに区切って配列とし,変数aに代入しています.例えばpの値が1357のとき,a = [1, 3, 5, 7]となります.次の「next if a.length > a.uniq.length」は,問題文に書いた「それぞれ異なる」のチェックをしていまして,配列の中に同じ数になるものがあれば,ifの条件式を満たすことになり,それ以降の処理を行わない(次の整数に移る)というものです.
 pとqの積をproductに,またaを逆順にしてから1個の整数値にしたものをp_revに代入し(a = [1, 3, 5, 7]のときprev = 7531),productとp_revの値が等しければ「当たり!」となるわけです.
 このプログラムを実行すると,ABCD×E=DCBAの解がすべて得られます.次のようになりました.

$ ruby fukumen.rb
2178 * 4 = 8712
1089 * 9 = 9801

 元ネタのp.25に記載の解と同じです…と思いきや,「そして,2178×4=8721を自分の力で発見するであろう。」と,積に誤記が入っていました.
 プログラムは引数を1つとり,これが,かけられる数の桁数となります.5桁,すなわちABCDE×F=EDCBAについても,解がありました.

$ ruby fukumen.rb 5
21978 * 4 = 87912

 他の桁数,具体的には2や3や,6以上では,解なしでした.桁が多くなると,「それぞれ異なる」を満たす割合が下がるので,桁数をむやみに増やしても意味がありません.
 条件を緩めます.「それぞれ異なるものとします」を除外して,解を求め直してみます(被乗数および積の最上位桁は0にならないこと,乗数は2以上9以下であることは,維持します).「next if a.length > a.uniq.length」の先頭に「#」をつけ,処理の対象外とするだけです.
 この場合にも,2桁や3桁のときは,解なしでした.4桁(デフォルト)の解は上記と同じでしたが,5以降が変わってきました.

$ ruby fukumen.rb
2178 * 4 = 8712
1089 * 9 = 9801
$ ruby fukumen.rb 5
21978 * 4 = 87912
10989 * 9 = 98901
$ ruby fukumen.rb 6
219978 * 4 = 879912
109989 * 9 = 989901

 規則性が見えてきます.「219...978×4=879...912」「109...989×9 = 989...901」という式で表せます.いずれも「9...9」は,0個を含む「9」の連続した並びです.念のため,bcコマンドで「219999999978*4」を計算させてみると,出力は879999999912でした.
 こういう数は数学的に検討済みだろうなと思い,検索してみると,https://oeis.org/A078273の中に,「a(2178) = 8712, a(21978) = 87912, a(219978) = 879912, etc... with a(n)/n = 4」というのを見つけました.そこでリンクされている,https://oeis.org/A008918は,「4倍して数の並びが逆順になる整数」であり,https://oeis.org/A001232は「9倍して数の並びが逆順になる整数」です.4倍のほう,間に9の並びを挟むだけでなく,「2178?2178」として,「?」に0の並びや,21978を挟む(2178219782178×4=8712879128712)というのも,該当するのでした.
 「219...978×4=879...912」は,数学的帰納法で証明できそうです.9の並びの数をn(n≧0)としたとき,かけられる数を,p(n)=21\cdot10^{n+2}+(10^n-1)\cdot10^2+78,そしてかけ算の結果を,r(n)=87\cdot10^{n+2}+(10^n-1)\cdot10^2+12と表せます.証明したい式はr(n)=4p(n)です.
 n=0のときは,2178×4=8712ですので成立します.
 n=kのとき成り立つと仮定します.この仮定はあとで使うことにして,p(n)の定義より,p(k+1)−p(k)=22\cdot9\cdot10^{k+2}となります(k=0のとき,この右辺は19800であり,21978-2178も同じ値です).同様に(k+1)−r(k)=88\cdot9\cdot10^{k+2}となり,r(k+1)−r(k)=4(p(k+1)-p(k))です.r(k+1)−4p(k+1)=r(k)−4p(k)と変形すると,帰納法の仮定から右辺が0となるので,左辺も0であり,r(k+1)=4p(k+1)を得まして,これは,n=k+1のときにも成り立つことを意味します.
 「109...989×9 = 989...901」のほうは,同様に式をおいてひき算をすると,9\cdot10^{k+2}の11倍と99倍が出てきます.

(最終更新:2019-05-29 深夜.Rubyコードの解説を充実させました)