이 문제에서 재미있는 프로시저 하나를 얘기합니다.

 

해당 프로시저를 처음 봤을 때 무슨 프로시저인가 고민했습니다.

왜 num에 radix를 곱하는지, 다음으로 넘길 때 왜 remainder를 써서 나머지를 넘기는지

그 이유를 알 수 없었습니다.

 

그래서 책에 나오는 예제인 (expand 1 7 10)을 따라 해보았습니다.

1 4 2 8 5 7 1 4 2 8 5 7 1....

해당 연산을 하면서 어디서 많이 해보던 느낌이 많이 들었습니다.

몫을 기록하고 나머지에 10을 곱해 다시 몫을 기록하는 행위...

 

다음 예제인 (expand 3 8 10)을 따라 해보았습니다.

3 7 5 0 0 0 0 0 0 0...

여기까지 해보고나서 무엇인지 알게 되었습니다.

 

분수를 소수로 바꾸는 연산!

 

처음 예제는 1/7을 소수 0.1428571428571...로 표현한 것이고,

두 번재 예제는 3/8을 소수 0.375로 표현한 것입니다.

 

이런 방법은 나눗셈 표기법으로 구하는 것과 동일합니다.

출처 : 3. 소수의 나눗셈

즉, 몫을 위에 적고 남은 나머지에 10을 곱해 다시 몫을 구하는 것과 동일합니다.

 

어렸을때부터 언제나 하였던 것임에도 이렇게 보니 신기하네요.

그만큼 창의성이 없다는 뜻인지도...OTL.....

 

 

참조

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

 

 

; 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)))))))))

; answer
(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))

(define (expands num den radix)
  (cons-stream
   (quotient (* num radix) den)
   (expands (remainder (* num radix) den) den radix)))

; execute
(define a (expands 1 7 10))
(define b (expands 3 8 10))
(print-stream-n a 10)
(newline) (newline)
(print-stream-n b 10)

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

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

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

댓글을 달아 주세요

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