SICP問題3.72

三通りの異なる方法で二つの平方数の和としてかける全ての数のストリームを生成する手続き(問題3.71と似た方法で実装)

(define (square-weight x)
  (let ((i (car x))
        (j (cadr x)))
    (+ (square i) (square j))))
(define square-weighted-stream
  (weighted-pairs integers integers square-weight))
(define (sum-of-two-square-sub s)
  (let ((s-weight (square-weight (stream-car s)))
        (t-weight (square-weight (stream-car (stream-cdr s))))
        (u-weight (square-weight (stream-car (stream-cdr (stream-cdr s))))))
    (if (= s-weight t-weight u-weight)
        (cons-stream s-weight
                     (sum-of-two-square-sub (stream-cdr s)))
        (sum-of-two-square-sub (stream-cdr s)))))
(define sum-of-two-suqare-three-way
  (sum-of-two-square-sub square-weighted-stream))

テスト

(stream-ref-range sum-of-two-suqare-three-way 0 5)
; 325
; 425
; 650
; 725
; 845
; #<undef>

上記実装はRamanujan数と同じ方法で行っている。
まずi<=jとなる全ての正の整数の組(i, j)を平方数の和i^2+j^2で重み付けした順のストリームを生成する。これらの組は平方数の和で重み付けされており、かつ各組の(i, j)は異なっているため、隣り合った三つの組の平方数の和が同じであれば、三通りの異なる方法で表せる二つの平方数の和のストリームを生成できる。よって上記実装となった。