이 문제는 두 power series의 곱을 구하는 프로시저를 작성하는 문제입니다.

빈칸을 채워 넣으면 되는 간단한 문제이지만,

어제부터 오늘까지 아무리 생각해도 틀에 맞춰 할 수 없었기에

제가 스트림에 대한 이해가 많이 부족하다는 것을 느꼈습니다.

 

결국 '이렇게 하면 되지 않을까?'와

'덧셈이 점점 증가하니 mul-series를 부르는 것과

나머지를 처리하는 프로시저를 불러 이를 더하면 되지 않을까?'라는 생각으로

여러 번 프로시저를 돌려 값을 확인하여 답을 구했습니다.

 

그렇게 답을 구했음에도 왜 저 코드가 맞는지는 이해가 되지 않습니다.OTL....

스트림은 재미있으면서도 새로운 구조라 그런지 제 머리에 인식이 잘 안되네요.ㅜ

 

제일 처음에 위와 같은 코드를 짰습니다.

쉽게 생각한 것이지요.

그런데 sin²x + cos²x의 값이 1이 나왔기에 맞는 줄 알았습니다.

하지만 이상하다는 생각에 e^x를 두 번 곱한 값을 출력하도록 하였습니다.

 

위의 결과는 MATLAB을 이용해서 얻었습니다.

즉, e^2x의 값이 틀렸다는 것을 알 수 있었습니다.

 

그 이후로 이렇게 맞춰보고 저렇게 맞춰보고 연습장에 적어가며 답을 맞춰보았습니다.

그러다 결국 답에 도착하였습니다.

 

두 개 모두 맞다는 것을 확인할 수 있습니다.

 

 

이 문제를 맞추는데 최종적으로 다른 이의 답이 도움이 되었습니다.

'SICP Exercise 3.60.'

이에 감사의 인사를 드립니다.

 

 

참조

해럴드 애빌슨, 김재우 역, <컴퓨터 프로그램의 구조와 해석>, 인사이트, 2007, pp. 434

 

 

; stream
(define true (= 0 0))
(define false (= 1 0))

(define (cons-stream a b)
  (cons a (delay b)))
(define the-empty-stream '())
(define stream-null? null?)
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))

; section 3.5
(define (stream-ref s n)
  (if (= n 0)
      (stream-car s)
      (stream-ref (stream-cdr s) (- n 1))))

(define (stream-for-each proc s)
  (if (stream-null? s)
      'done
      (begin (proc (stream-car s))
             (stream-for-each proc (stream-cdr s)))))

(define (display-stream s)
  (stream-for-each display-line s))

(define (display-line x)
  (newline)
  (display x))

(define (stream-enumerate-interval low high)
  (if (> low high)
      the-empty-stream
      (cons-stream
       low
       (stream-enumerate-interval (+ low 1) high))))

(define (stream-filter pred stream)
  (cond ((stream-null? stream) the-empty-stream)
        ((pred (stream-car stream))
         (cons-stream (stream-car stream)
                      (stream-filter pred
                                     (stream-cdr stream))))
        (else (stream-filter pred (stream-cdr stream)))))

(define (memo-proc proc)
  (let ((already-run? false) (result false))
    (lambda ()
      (if (not already-run?)
          (begin (set! result (proc))
                 (set! already-run? true)
                 result)
          result))))

(define (scale-stream stream factor)
  (stream-map (lambda (x) (* x factor)) stream))

; exercise 3.50
(define (stream-map proc . argstreams)
  (if (stream-null? (car argstreams))
      the-empty-stream
      (cons-stream
       (apply proc (map stream-car argstreams))
       (apply stream-map
              (cons proc (map stream-cdr argstreams))))))

;;;SECTION 3.5.2
(define (add-streams s1 s2)
  (stream-map + s1 s2))

(define ones (cons-stream 1 ones))
(define integers (cons-stream 1 (add-streams ones integers)))

; exercise 3.54
(define (mul-streams s1 s2)
  (stream-map * s1 s2))

; exercise 3.56
(define (merge s1 s2)
  (cond ((stream-null? s1) s2)
        ((stream-null? s2) s1)
        (else
         (let ((s1car (stream-car s1))
               (s2car (stream-car s2)))
           (cond ((< s1car s2car)
                  (cons-stream s1car (merge (stream-cdr s1) s2)))
                 ((> s1car s2car)
                  (cons-stream s2car (merge s1 (stream-cdr s2))))
                 (else
                  (cons-stream s1car
                               (merge (stream-cdr s1)
                                      (stream-cdr s2)))))))))

; print-stream-n
(define (print-stream-n S n)
  (define (iter i)
    (if (= i n)
        'done
        (begin (display (stream-ref S i))
               (display "  ")
               (if (= (remainder (+ i 1) 10) 0)
                   (newline))
               (iter (+ i 1)))))
  (iter 0))

; exercise 3.59
(define (div-streams s1 s2)
  (stream-map / s1 s2))

(define (integrate-series coff_stm)
  (let ((integrate_s (cons-stream 1 ; 상수 c
                                  (div-streams coff_stm integers))))
    (stream-cdr integrate_s)))

(define exp-series
  (cons-stream 1 (integrate-series exp-series)))
(define cosine-series
  (cons-stream 1
               (integrate-series (scale-stream sine-series -1))))
(define sine-series
  (cons-stream 0
               (integrate-series cosine-series)))

; exercise 3.60
(define (mul-series s1 s2)
  (cons-stream (* (stream-car s1) (stream-car s2))
               (add-streams (mul-series (stream-cdr s1) s2)
                            (scale-stream (stream-cdr s2) (stream-car s1)))))
; execute
(define a (add-streams (mul-series sine-series sine-series)
                       (mul-series cosine-series cosine-series)))
(print-stream-n cosine-series 10)
(print-stream-n sine-series 10)
(newline)
(print-stream-n a 10)
(newline) (newline)

(define b (mul-series exp-series exp-series))
(print-stream-n exp-series 6)
(newline)
(print-stream-n b 6)

크리에이티브 커먼즈 라이선스
Creative Commons License

글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.

트랙백 주소 :: http://nosyu.pe.kr/trackback/1619

댓글을 달아 주세요

[로그인][오픈아이디란?]