練習問題2.4

同じ c の値に対する例を見つけよ。

s=199 でプログラムで調べました。
(make-pythagoras 手続きの引数 limit に 199 を与えました。)

(define nil '())

(define (square x)
  (* x x))

(define (euclid-gcd a b)
  (if (= b 0)
      a
      (euclid-gcd b (remainder a b))))

(define (uniq lis)
  (define ht (make-hash-table 'equal?))
  (define (iter l)
    (if (null? l)
	(hash-table-keys ht)
	(let ((key (hash-table-get ht (car l) nil)))
	  (and (null? key) (hash-table-put! ht (car l) (car l)))
	  (iter (cdr l)))))
  (iter lis))

;;

(define (pythagoras s t)
  (let ((a (* s t))
        (b (/ (- (square s) (square t)) 2))
        (c (/ (+ (square s) (square t)) 2)))
    `(,a ,b ,c)))

(define (make-pythagoras limit)
  (define (iter-t s t lis)
    (if (< t 1)
        lis
        (iter-t s (- t 2) (if (= (euclid-gcd s t) 1)
                              (append (list (pythagoras s t)) lis)
                              lis))))
  (define (iter-s s lis)
    (if (< s 3)
        lis
        (iter-s (- s 2) (append (iter-t s (- s 2) nil) lis))))
  (if (even? limit)
      (error "limit required odd number")
      (iter-s limit nil)))

重複している数を数えるのには、Pharo を使いました。
まず Scheme にて

gosh> (define p (make-pythagoras 199))
p
gosh> (define c (map caddr p))
c

として c のみのリストを作りプリントします。

gosh> (print c)

これを Pharo の Playground に貼り付けて、

#(5 13 17 25 29 37 41 53 65 61 65 73 85 101 85 89 97 109 ...) asBag

長いので後ろを省略しますが、リテラルをつけて Array オブジェクトにし、
asBag メッセージを送って Bag オブジェクトに変換します。
これをインスペクトすれば重複しているものが簡単にわかります。

結果発表ー!

・2つ
65 の次に大きいものは 85。他にもたくさんあります。

77^2 + 36^2 = 85^2
13^2 + 84^2 = 85^2

・3つ
20213。他にもあります。

20115^2 + 1988^2 = 20213^2
17325^2 + 10412^2 = 20213^2
9555^2 + 17812^2 = 20213^2

・4つ
1105。他にもあります。

1073^2 + 264^2 = 1105^2
943^2 + 576^2 = 1105^2
817^2 + 744^2 = 1105^2
47^2 + 1104^2 = 1105^2

5つ以上のものは見つかりませんでしたが、s をもっと大きな値にすれば見つかるかも知れません。