[taos-glug] Question 1.46

  • From: Jonathan Bartlett <johnnyb@xxxxxxxxxx>
  • To: taos-glug@xxxxxxxxxxxxx
  • Date: Tue, 12 Aug 2003 14:29:39 -0700 (PDT)

Here's my answer to Q 1.46.  I think it could be written better, but it
didn't occur to me how.

;This is the base procedure.  It is only used as a gateway to the
;recursive
;procedure below (*NOTE - with Y-combinators you don't have to define a
;separate procedure - you can embed the recursive call within your
;function
;- but they are too evil to actually be of value).  It takes a function
;check-guess, which checks it's guess, and improve-guess, which improves
;it.

(define iterative-improve (lambda (check-guess improve-guess)
        (lambda (guess)
                (iterative-improve-recursive check-guess improve-guess
guess)
        )
))


(define iterative-improve-recursive (lambda (check-guess improve-guess
current-guess)
        ;Is the current guess good enough?
        (if (check-guess current-guess)
                ;Yeah! It is! Return and we're done.
                current-guess
                ;Nope, call this function again with an improved guess
                (iterative-improve-recursive
                        check-guess
                        improve-guess
                        (improve-guess current-guess)
                )
        )
))

;Okay, here's the function that the user calls.  They give a number
;to square and how precise they want their answer.  The number is
;used as the initial guess

(define square-root (lambda (number precision)
        (let
                (
                        ;Define the procedure to check guesses
                        ;Basically, square the number, and see how
                        ;close it is to the actual answer
                        (check-guess (lambda (guess)
                                (if (> (abs (- (* guess guess) number))
precision)
                                        #f
                                        #t
                                )
                        ))
                        ;Define a procedure which uses newton's method to
                        ;get new guess for our square root
                        ;It is the average of guess + number/guess
                        (improve-guess (lambda (guess)
                                (/ (+ guess (/ number guess)) 2)
                        ))
                )
                ;Remember, iterative-improve returns a procedure, and
                ;we then call that procedure with our first guess
                ((iterative-improve check-guess improve-guess) 5)
        )
))

I don't know if it's the best solution, but it's the first I thought of.

Jon


Other related posts: