count-change
SICPの関数のコードを変更して、関数が繰り返されるたびにペアが表示されるようにしました。ペアはまたはの形式です"(cc a k)" -> "(cc a (- k 1))"
。"(cc a k)" -> "(cc (- a (d k)) k)"
私の目標は、GraphVizを使用してツリー再帰を表示するDOTファイルを作成することです。
以下のコードから生成された画像の例を次に示します。
スキームコードは次のとおりです。
; Count Change
(define (count-change amount)
(cc amount 5))
(define (cc amount kinds-of-coins)
(begin
(cond ((= amount 0) 1)
((or (< amount 0) (= kinds-of-coins 0)) 0)
(else (+
(begin
(display "\"")
(display `(cc ,amount ,kinds-of-coins))
(display "\"")
(display " -> ")
(display "\"")
(display `(cc ,amount ,(- kinds-of-coins 1)))
(display "\"")
(display "\n")
(cc amount (- kinds-of-coins 1))
)
(begin
(display "\"")
(display `(cc ,amount ,kinds-of-coins))
(display "\"")
(display " -> ")
(display "\"")
(display `(cc ,(- amount (first-denomination kinds-of-coins)) ,kinds-of-coins))
(display "\"")
(display "\n")
(cc (- amount (first-denomination kinds-of-coins)) kinds-of-coins)
)
)
))))
; first-denomination takes the number of kinds of coins and returns the denomination of the first kind
(define (first-denomination kinds-of-coins)
(cond ((= kinds-of-coins 1) 1)
((= kinds-of-coins 2) 5)
((= kinds-of-coins 3) 10)
((= kinds-of-coins 4) 25)
((= kinds-of-coins 5) 50)))
(count-change 11)
元のコードはこちらです。
begin
スキームマクロについて読んだことがありますが、再帰時に何が起こっているかを出力するために、ディスプレイ付きのステートメントで(cc。。)への呼び出しを「ラップ」できるようにすることでこの問題を解決できると思います。
これはSchemeマクロでどのように行うことができますか?
注:画像が不正確であることはわかっています。グラフがDAGだけでなくツリーになるように、ノードを区別する方法を見つける必要があります。ただし、それはこの質問の範囲外です。