練習問題1.1

練習問題をプログラムを自分で書いて解いて行きます。
プログラミング言語Scheme を使います。数学の問題を解くのに Lisp (Scheme) は最適でありましょう。

のっけから難しいです(汗

a.平方数でも三角数でもある数を見つけなさい。

まずは愚直な実装で数値の傾向を探ります。教科書 12 ページにも数学的方法を考えるためのまとめがあるのですが、いままで行っていたアプローチで良いのですね。ちょっと安心しました。

(define nil '())

(define (total n)
  (/ (* n (+ n 1)) 2))

(define (p01-1 limit)
  (define (iter n lis)
    (if (> n limit)
        lis
        (let ((t (total n)))
          (iter (+ n 1)
                (if (integer? (sqrt t))
                    (append lis (list (list n t)))
                    lis)))))
  (iter 1 nil))

limit を 1,000,000 にして実行します。少し時間がかかりますが、三角数と平方数が求まります。

((1 1) (8 36) (49 1225) (288 41616) (1681 1413721) (9800 48024900) (57121 1631432881) (332928 55420693056))

36 の次の数は 1225、その次の数は 41616 です。

b.三角数であり平方数である数を見つける有効な方法を見つけることはできるか?

三角数 平方する前の数        平方数
     1              1             1
     8              6            36
    49             35          1225
   288            204         41616
  1681           1189       1413721
  9800           6930      48024900
 57121          40391    1631432881
332928         235416   55420693056

例によって Excel 先生に貼り付けて分析すると、数値の傾向が見えてきます。
分析が完了したら平方数を計算で求めるプログラムを書きます。

(define nil '())
 
(define (p01-1 count)
  (define (iter c heihou hosei result)
    (if (<= c 1)
        result
        (let ((next (- (* heihou 6) hosei)))
          (iter (- c 1) next heihou (append result (cons (* next next) nil))))))
  (if (< count 1)
      nil
      (iter count 1 0 '(1))))

「平方する前の数」を 6 倍して数値補正をします。この補正値には「平方する前の数」が現れていますね。ちなみに三角数は、「平方する前の数」から1つ手前の「三角数」と「平方する前の数」を足すと求まります。例えば、3つめの三角数は、「平方する前の数」の 35 に一つ手前の答え 8 + 6 = 14 を足して 49 です。以下同様に求めることが出来ます。

実行してみます。

gosh> (p01-1 10)
(1 36 1225 41616 1413721 48024900 1631432881 55420693056 1882672131025 63955431761796)

平方数は計算で求めているので、10 個ぐらいならあっという間に求まります。
100 個でも余裕です。

gosh> (time (p01-1 100))
;(time (p01-1 100))
; real   0.001
; user   0.000
; sys    0.000
(1 36 1225 41616 1413721 48024900 1631432881 55420693056 1882672131025 63955431761796 2172602007770041 73804512832419600 2507180834294496361 85170343853180456676 2893284510173841030625 98286503002057414584576 3338847817559778254844961 113422539294030403250144100 3853027488179473932250054441 130889512058808083293251706896 4446390382511295358038307980025 151046383493325234090009219613956 5131130648390546663702275158894481 174307395661785261331787346182798400 5921320321852308338617067495056251121 201150583547316698251648507485729739716 6833198520286915432217432187019754899225 232127599106207807997141045851185936833936 7885505171090778556470578126753302097454601 267875048217980263112002515263761085376622500 9099866134240238167251614940841123600707710401 309127573515950117423442905473334441338685531136 10501237633408063754229807171152529881914600348225 356732951962358217526390000913712681543757726308516 12118419129086771332143030223895078642605848094141321 411669517436987867075336637611518961167055077474496400 13984645173728500709229302648567749601037266786038736281 475066266389332036246720953413691967474100015647842537156 16138268412063560731679283113416959144518363265240607527025 548226059743771732840848904902762918946150251002532813381696 18623547762876175355857183483580522285024590170820875047450641 632652397878046190366303389536834994771889915556907218799940100 21491557980090694297098458060768809299959232538764024564150512761 730080318925205559910981270676602681203842016402419927962317493776 24801239285476898342676264744943722351630669325143513526154644275625 842512055387289338091082020057409957274238915038477039961295587877476 28620608643882360596754112417206994824972492441983075845157895343558561 972258181836612970951548740164980414091790504112386101695407146093113600 33028157573800958651755903053192127084295904647379144381798685071822303841 1121985099327395981188749155068367340451968967506778522879459885295865216996 ...)

愚直な実装では 100 個求めるのは不可能でしょう。いつまで経っても計算が終わらないと思います。


なお、数値の傾向から探っただけですので、「平方する前の数は、どうして 6 倍して補正値を引く」事で求められるのかはわかりません(汗 1 の次は 36 なので傾向を探るには不適です。36 の次は 1225 なので図とかを描いて確認するにも大変すぎて無理です。

c.こうした性質を持つ数は無数にあると考えられるか?

整数は無数にあり、平方数もまた無数にあります。三角数は「平方する前の数」から求めることが出来るので、これも無数にあります。よって、「三角数であり平方数である数」は無数にあると言えます。