計算機プログラムの構造と解釈 第二版 P44 問題1.46

とうとう一章の最後の問題ですね。


いきなり反復改良法とか言ってビビるけど心配なし。
説明は書いてある。


題意をつかむ。
ふむふむつまり、


1.iterative-improveと言う手続きを作る。


この手続きには引数として
・予測値が十分良好であるか調べる手続き
・予測値を改良する方法をとる手続き


この手続きは返り値として
・予測値が十分良好になるまで改良を繰り返す手続き
を返す。


2.「1」で作った手続きを利用して、sqrtの手続きを作る
3.「1」で作った手続きを利用して、fixed-pointをつくる


って感じ。


「1」は何となく解る感じがする。


「2」と「3」のコツは、
・予測値が十分であるか調べる手続き

・予測値を改良する方法をとる手続き


の引数を、どうやって1つの引数にするかって、とこかな。
というか、僕が引っかかったのがそこ。


ということで、こういう結果になった。

#!/usr/local/bin/gosh
;; -*- coding: utf-8 -*-

;; iterative-improve
(define (iterative-improve fix enough?)
  (lambda (v) 
    (define (fix-i v)
      (if (enough? v)
        v   
        (fix-i (fix v))))
    (fix-i v)))


;;sqrt
(define (square x)
  (* x x)) 

(define (average x y)
  (/ (+ x y) 2.0))

(define (sqrt x)
  (define (improve guess)
    (average guess (/ x guess)))
  (define (good-enough? guess)
    (< (abs (- (square guess) x)) 0.001))
  ((iterative-improve improve good-enough?) x)) 


;; fixed-point
(define tolerance 0.00001)

(define (fixed-point f first-guess)
  (define (close-enough? v)
    (< (abs (- v (f v))) tolerance))
  ((iterative-improve f close-enough?) 1.0))


;; main
(define (main args)

  (display "(sqrt 25) : ")
  (display (sqrt 25))(newline)

  (display "(fixed-point cos 1.0) : ")
  (display (fixed-point cos 1.0))
  (newline)

  (newline)
0)


で実行結果

(sqrt 25) : 5.000023178253949
(fixed-point cos 1.0) : 0.7390893414033927


できたと思う。