SICP Exercise 연습문제 2.44

By | 2008/02/17

SICP 연습문제 2.42와 2.43은 잘 풀리지 않고, 의문점이 있어 미루었습니다.

 

이 문제는 그림언어라는 재미있어보이는(아직 덜 배웠기에…) 내용의 문제입니다.

본문에 이미 corner-split 프로시저가 있기에 up-split는 금방 만들었습니다.

 

c5

제대로 잘 되는군요.^^

 

 

조금 번외의 얘기이지만 진행하겠습니다.

다른 분들이 이 문제를 푼 것을 보니 간단히 up-split 프로시저만을 만들었습니다.

하지만 한 곳에서 그 결과까지 보여주었습니다.

SICP Exercise 2.44.

 

그 글을 보니 약간 약이 올랐습니다.

‘일본인도 하였는데, 나라고 못하겠느냐!’

거기에 그의 블로그를 살펴보니 진도가 엄청 나갔더군요.

‘내가 밀린다는 말인가. 그럼 나도 할 수있다는 것을 보여주마!’

이런 생각으로 열심히 구글링을 하면서 찾았습니다.

하지만 MIT에서 제공하는 Scheme는 그 사용방법을 잘 몰라 쓰지 못하고,

제가 쓰고 있는 DrScheme는 below와 beside 프로시저를 제공하지 않습니다.

 

 

어떻게 해야하나 한참을 고민하고 찾아보니

PLaneT Package라는 것을 찾았습니다.

그것은 유저가 만드는 플러그인과 같은 것으로

거기에 SICP 2.4.4절과 관련된 것이 있습니다.

The SICP Picture Language

 

‘좋다구나~’라는 생각으로 설치를 하였습니다.

설치는 간단히 ‘(require (planet “sicp.ss” (“soegaard” “sicp.plt” 1 1)))’라는 식을

실행기에 적기만 하면 자동으로 설치가 됩니다.

 

 

하지만 프로시저를 돌려보니 제가 원하는 결과가 아니었습니다.

그림이 거꾸로 나오는 것입니다.

왜 그런가 싶어 below 프로시저를 살펴보니 다음과 같이 되어있습니다.

(define (below painter1 painter2)
(rotate270 (beside (rotate90 painter2)
(rotate90 painter1))))

(출처 : hend.scm)

 

방법은 다음과 같습니다.

두 개의 painter를 받아 각각 시계방향으로 90도 회전시킨 후

두 번째 painter 오른쪽에 첫 번째 painter를 붙입니다.

그 후 다시 시계방향으로 270도 회전, 즉 반시계방향으로 90도 회전시킵니다.

그럼 위아래로 붙이는 효과가 나타납니다.

 

하지만 저처럼 작동시키면 painter1 밑에 painter2가 들어갑니다.

SICP책에서는 이렇게 below를 설명하고 있습니다.

‘below 연산은, 첫 번째 페인터가 두 번째 페인터 그림 아래에다 그림을 그리도록,’

(출처 : SICP 168쪽)

따라서 위의 연산은 반대로 된 것입니다.

 

더욱 황당하게도 example.scm을 보니 답과 반대로 되어 있습니다.

(출처 : example.scm)

따라서 작동은 잘 되지만, 다른 부분에서 below를 부르면 반대의 결과가 나옵니다.

 

 

이를 수정하고자 먼저 제작자의 연락처를 찾았습니다.

하지만 아무리 찾아도 보이지 않더군요.

혹시 제가 가입하면 수정이 가능한가 싶어 살펴보니 그것도 아니었습니다.

그래서 제가 직접 소스 파일을 가져와 plt 파일을 만들고자 했습니다.

하지만 만들어져도 제대로 설치가 되지 않더군요.OTL…

 

결국 example.scm에 있는 방식인 require 프로시저를 쓰는 방법으로

변경한 소스를 연습문제 소스가 있는 폴더에 넣었습니다.

그러자 작동을 제대로 합니다.

 

 

제작자 연락처만 있다면 간단히 해결될 문제에 너무 시간을 많이 뺏겨버려

이 다음 문제를 풀 시간이 없어졌습니다.OTL…

좋은 패키지를 만들고서 왜 기본적인것에서 빗나갔는지도 조금 원망스럽네요.ㅜㅜ

마지막으로 plt를 만들지 못한 제가 한심합니다.ㅜㅜ

 

다른 분들은 저와 같은 삽집을 하지 않기를 바라면서 수정한 소스를 올리겠습니다.

해당 소스의 라이선스를 잘 모르겠습니다만,

연락처도 없고 소스는 공개되어있어 수정배포합니다.

 

003.zip

 

해당 소스를 쓰는 방법은 연습문제 소스 파일이 있는 폴더에 압축을 푸신 후

소스 첫 부분에 ‘(require “paint/painters.ss”)’라는 식을 넣으시면 됩니다.

 

 

프로그램 안의 그림은 최근 불타버린 숭례문으로 하였습니다.

사진은 제가 직접 찍은 것입니다.

 

 

참조

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

http://blog.goo.ne.jp/msyksphinz

http://planet.plt-scheme.org

 

 

;(require (planet “sicp.ss” (“soegaard” “sicp.plt” 1 1)))
; 위의 것이 좋으나 below 프로시저가 잘못되어있어 부득이하게 고친 것을 가져옴.
(require “paint/painters.ss”)

; answer
(define (up-split painter n)
  (if (= n 0)
      painter
      (let ((smaller (up-split painter (- n 1))))
        (below painter (beside smaller smaller)))))
; execute
(define Sungnyemun
  (load-painter
   (build-path “Sungnyemun.jpg”)))
(paint (up-split Sungnyemun 3))

Leave a Reply