본문 바로가기

LISP?

[학습] 뉴튼법으로 제곱근, 세제곱근 구하기

;; 뉴튼법: 알고자 하는 값을 차례로 되풀이해서 구해나가는 방법

;; 제곱근 구하기
;; x의 제곱근에 가까운 값 y(guess)가 있을 때, y와 x/y 의 평균(더 근접한 guess)을
;; 구하여 진짜 제곱근에 더 가까운 값을 구하는 방법이다.

;; 참값에 더 가까운 값 guess를 구하기 위해 어림잡은 값을 조금씩 고쳐나가면서
;; 헌 값에 견주어 고친 값이 그다지 나아지지 않을 때까지 계산을 이어가는 방식이다.

;; 큰 문제를 작은 문제로 나누어 푸는 방식을 적용한 LISP
;; 프로시저 하나를 조립식 부품(module)처럼 만들어 다른 프로시저를 정의할 때
:: 쓸 수 있도록 일 단위로 잘라내는 것이 진짜 중요하다.
;; 프로시저를 쓰는 사람은 그것이 무슨 일을 하는지만 알면 되지, 굳이 그것이 어떻게
:: 만들었는지 몰라도 된다.
;; 어떤 문제를 푸는 데에 어떤 식으로 프로그래밍 언어를 써야 할까?
;; 어떤 전략이나 전술을 펼쳐야 할까?

;; 스스로 새로운 무언가를 만들어 내는 일을 할 때는 언제나 그러하듯이
;; 프로그램 짜는 일을 하는 사람이라면 어떤 일을 하고 나서 어떤 결과가 나올지
;; 머릿속에 그려낼 줄 알아야 한다.
;; 어떤 일을 하기 위해 어떤 프로세스를 밟아야 할지 미리 정해 놓으려고 짜는 게
:: 프로그램이다.
;; 그러므로 전문가가 되려면 여러 가지 프로시저가 만들어 내는 프로세스를 미리
;; 그려낼 수 있도록 공부해야 한다. 이런 기술을 깨닫고 익힌 다음에야 생각한 대로
;; 돌아가는 프로그램을 어떻게 짜는지 배울 수 있다.


(defun sqrt-iter (guess x)
  (if (good-enough? guess x)
      guess
    (sqrt-iter (improve guess x) x))) 
   
(defun improve (guess x)
              (average guess (/ x guess)))
             
(defun average (x y)
              (/ (+ x y) 2))

(defun good-enough? (guess x)
                  (< (abs (- (square guess) x)) 0.001))
                 
(defun square (x)
                   (* x x))


;;; 프로시제 실행하기
(sqrt-iter 1.0 2)   
;;; ===>
1.4142157


;;; 개선된 제곱근 구하는 LISP - 블랙박스처럼 간추린 프로시저
;;; 부속 프로시저들을 감추었기 때문에 다른 프로시저에서 good-enough?
;;; 이나 improve guess 등을 다시 정의하여 쓸 수 있게 된다.
;;; 밑에서부터 거꾸로 세워나가는 식의 프로그래밍 같다.

(defun re-sqrt (x)
 (defun square (a)
  (* a a))
 (defun good-enough? (guess)
  (< (abs (- (square guess) x)) 0.001))
 (defun average (a b)
  (/ (+ a b) 2))
 (defun improve (guess)
  (average guess (/ x guess)))
 (defun sqrt-iter (guess)
  (good-enough? guess)
  guess
  (sqrt-iter (improve guess)))
 (sqrt-iter 1.0))

(re-sqrt 5)



;; 세제곱근 구하기

(defun cube-root (guess x)
  (if (good-enough? guess x)
      guess
    (cube-root (improve guess x) x))) 
   
(defun improve (guess x)
              (/ (+ x (* guess guess) (* 2 guess)) 3))
             
(defun good-enough? (guess x)
                  (< (abs (- (* guess guess guess) x)) 0.01))


;;; 프로시제 실행하기

(cube-root 3.0 27)    
;;; ===>
3.0