Q1: ビラハンカ フィボナッチ
n 番目のビラハンカ フィボナッチ数を返す関数を作成します。
(define (vir-fib n)
(cond
((< n 2) n)
(else (+ (vir-fib (- n 1)) (vir-fib (- n 2))))
)
)
(expect (vir-fib 2) 1)
(expect (vir-fib 10) 55)
(expect (vir-fib 1) 1)
Q2: リスト作成
いくつかの Scheme リストを作成しましょう。同じリストを list、quote、cons で定義します。次のリストは、code.cs61a.org の描画機能を使用して視覚化されたものです。
まず、リストを使用します。
(define with-list
(list
(list 'a 'b) 'c 'd (list 'e)
)
)
(draw with-list)
ここで引用符を使用します。どのような違いがありますか?
(define with-quote
'(
(a b) c d (e)
)
)
(draw with-quote)
今度は短所を試してみましょう。便宜上、helpful-list と another-helpful-list を定義しました。
(define helpful-list
(cons 'a (cons 'b nil)))
(draw helpful-list)
(define another-helpful-list
(cons 'c (cons 'd (cons (cons 'e nil) nil))))
(draw another-helpful-list)
(define with-cons
(cons
helpful-list another-helpful-list
)
)
(draw with-cons)
Q3: リストの連結
2 つのリストを受け取り、それらを連結する関数を作成します。
単純に (cons ab) を呼び出すと、深いリストが作成されるため機能しないことに注意してください。組み込みプロシージャ append は list-concat と同じことを行うため、呼び出さないでください。
'See from stackoverflow
(define (list-concat a b)
(if (null? a)
b
(cons (car a) (list-concat (cdr a) b))
)
)
'My realization
(define (list-concat-1 a b)
(if (null? a)
(if (null? b)
()
(list-concat b ())
)
(cons (car a) (list-concat (cdr a) b))
)
)
(expect (list-concat '(1 2 3) '(2 3 4)) (1 2 3 2 3 4))
(expect (list-concat '(3) '(2 1 0)) (3 2 1 0))
授業でcdr
、これはデコレータ レジスタ の内容を意味し、アドレス レジスタ の内容をcar
意味すると聞きました。これら 2 つの名前は、MIT が使用するコンピュータの 2 つのレジスタの名前から来ています (おそらく間違っています) が、これら 2 つのレジスタは現在では使用されていませんこれは問題であり、教師はまた、このキーワードを変更される可能性のあるハードウェア名に結び付けないことが最善であることを示す、この奇妙な命名方法について遺憾の意を表明しました。
リストである限り(cdr list)
ネストは発生しませんが、(car list)
リストの場合、結果はネストされたリストになります。
Q4: 地図
プロシージャを受け取り、それを指定されたリスト内のすべての要素に適用する関数を作成します。
(define (map-fn fn lst)
(cond
((null? lst) nil)
(else (cons (fn (car lst)) (map-fn fn (cdr lst))))
)
)
(map-fn (lambda (x) (* x x)) '(1 2 3))
; expect (1 4 9)
Q5: ツリーを作成する
次の情報を入力して、ツリー データの抽象化を完了します。
(define (make-tree label branches) (cons label branches))
(define (label tree)
(car tree)
)
(define (branches tree)
(cdr tree)
)
(make-tree 1 (list (make-tree 2 '()) (make-tree 3 '())))
; expect (1 (2) (3))
Q6: 木の合計
上記のデータ抽象化を使用して、エントリがすべて数値であると仮定して、ツリーのエントリを合計する関数を作成します。
ヒント: リストのエントリを合計するには、マップをヘルパー関数とともに使用するとよいでしょう。
(define (map-fn fn lst)
(cond
((null? lst) nil)
(else (cons (fn (car lst)) (map-fn fn (cdr lst))))
)
)
(map-fn (lambda (x) (* x x)) '(1 2 3))
; expect (1 4 9)
(define (make-tree label branches) (cons label branches))
(define (label tree)
(car tree)
)
(define (branches tree)
(cdr tree)
)
(make-tree 1 (list (make-tree 2 '()) (make-tree 3 '())))
; expect (1 (2) (3))
(define (tree-sum-helper lst)
(cond
((null? lst) 0)
(else (+ (car lst) (tree-sum-helper (cdr lst))))
)
)
(define (tree-sum tree)
(cond
((null? tree) 0)
(else (cond
((null? (branches tree)) (label tree))
(else (+ (label tree) (tree-sum-helper (map-fn tree-sum (branches tree)))))
)
)
)
)
(define (sum lst)
(cond
((null? lst) 0)
(else (+ (car lst) (sum (cdr lst))))
)
)
(define t (make-tree 1 (list (make-tree 2 '()) (make-tree 3 '()))))
(expect (tree-sum t) 6)
そうしていると、内部の2つのcond
結果が逆転して という出力が発生してしまい1
、しばらく探して発見しました。