それは楽しかった!
わかりました、それが宿題ではなかったことを本当に願っています。
非常に単純な再帰的な解決策があることがわかりました。各レベルで必要なのは、ツリーのリストを取得し、それらをペアで集めてより深いツリーにし、このレベルで新しい葉を追加することです。これは「foldr」を使用して記述できますが、少しわかりにくいと思いました。
入力を少し明確にする必要があります。あなたが言及したページでは、仕様は次のようになります
レベル 0 の
葉 : レベル 1 の
葉 : レベル 2 の葉 : x23、x42、x23
レベル 3 の葉 : x24、x23
これは入力に対応します
'(() () (x23 x42 x23) (x24 x23))
以下のプログラムに。
また、ここで行われているのは、このテーブルをバイナリ ツリーにマッピングすることだけです。これは、デコード時にのみ役立ちます。エンコードの場合、このバイナリ ツリーは役に立ちません。
最後に、 How To Design Programsに大声で叫びます。私は慎重にデザインのレシピに従い、すべての i をドットで囲み、すべての t を交差させました。最初にテストケースをお願いします!
乾杯!
ジョン・クレメンツ
#lang racket
(require rackunit)
;; a tree is either
;; a symbol, or
;; (list tree tree)
;; a specification is
;; (listof (listof symbol))
;; spec->tree : specification -> tree
;; run spec->treelist, ensure that it's a list of length 1, return it.
(define (spec->tree spec)
(match (spec->treelist spec)
[(list tree) tree]
[other (error 'spec->tree "multiple trees produced")]))
;; spec->treelist : specification -> (listof tree)
;; given a *legal* specification, produce
;; the corresponding tree. ONLY WORKS FOR LEGAL SPECIFICATIONS...
(define (spec->treelist spec)
(cond [(empty? spec) empty]
[else (append (first spec) (gather-pairs (spec->treelist (rest spec))))]))
;; go "up one level" by grouping each pair of trees into one tree.
;; The length of the list must be a number divisible by two.
(define (gather-pairs trees)
(match trees
[(list) empty]
[(list-rest a b remaining) (cons (list a b) (gather-pairs remaining))]
[other (error 'gather "improperly formed specification")]))
;; TEST CASES
(check-equal? (gather-pairs '(a b c d)) '((a b) (c d)))
(check-equal? (spec->treelist '((top))) '(top))
(check-equal? (spec->treelist '(() (two-a two-b))) '((two-a two-b)))
(check-equal? (spec->treelist '(() (two-a) (three-a three-b)))
'((two-a (three-a three-b))))
(check-equal? (spec->treelist '(() () (three-a three-b three-c) (four-a four-b)))
'(((three-a three-b) (three-c (four-a four-b)))))
(check-equal? (spec->tree '(() () (three-a three-b three-c) (four-a four-b)))
'((three-a three-b) (three-c (four-a four-b))))