sicp每日一題[2.44]

再思即可發表於2024-10-14

我在這一章遇到了一個大問題,就是書上用的那些函式 beside, wave, flip-vert 我統統用不了。我用的是 DrRacket 這個軟體,在網上查了半天,終於找到了解決辦法。
首先是官方教程,在 DrRacket 中依次開啟 File -> Package Manager...,在彈出的頁面中 "Do What I Mean" 選單頁的輸入:sicp,回車之後自動安裝就行了。
但是我試了好幾次,總是因為網路問題沒法下載成功,最後求助於 chatgpt 終於解決了。
首先是手動下載 sicp 包到 Racket 安裝目錄,然後開啟 cmd 命令列,輸入 raco pkg install ./sicp 即可用本地的 sicp 目錄安裝包。
安裝好之後,重啟 DrRacket 軟體,依次點選上方選單欄的 Language -> Choose Language,在彈出的頁面中,找到 Teaching Languages(ctl-T) 下選擇 SICP(PLaneT 1.18),點選 OK。
再次回到程式碼編輯頁面後,就不需要開頭的 #lang racket 了,直接寫程式碼就行。
還有一點,安裝的 sicp 包裡也是沒有 wave, rogers 的,但是提供了 einstein,所以可以用 (define wave einstein) 替換掉或者把書上所有程式碼裡的 wave 都用 einstein 代替。不過直接在檔案裡輸入 einstein 或者 wave 是看不到圖象的,而是以以 #procedure 的形式存在的,需要用 (paint einstein) 顯式地呼叫,這樣就可以看到愛神的頭像了。

Exercise 2.44

Define the procedure up-split used by corner-split. It is similar to right-split, except that it switches the roles of below and beside.


這道題非常的簡單,就像題目所說的那樣,只要交換 below 和 beside 的位置就行。

(paint (right-split wave 1))

(define (up-split painter n)
  (if (= n 0)
      painter
      (let ((smaller (up-split painter (- n 1))))
        (below painter (beside smaller smaller)))))

(paint (up-split wave 1))

(define (corner-split painter n)
  (if (= n 0)
      painter
      (let ((up (up-split painter (- n 1)))
            (right (right-split painter (- n 1))))
        (let ((top-left (beside up up))
              (bottom-right (below right right))
              (corner (corner-split painter (- n 1))))
          (beside (below painter top-left)
                  (below bottom-right corner))))))

(paint (corner-split wave 1))
(paint (corner-split wave 2))

效果如下圖:



不過這是全新的內容,我覺得最好先理解 below 和 beside 的作用,其實就是字面意思,beside 是把2個圖形左右排列,第一個圖形在左邊;below 是把2個圖形上下排列,但是要注意它是把第二個圖形放在上面,如下圖所示:

(define wave einstein)

(paint (beside wave (below wave wave)))
(paint (below (beside wave wave) wave))


相關文章