I am trying to write a function, (codeWords t)
, which traverses a Huffman tree (adds #\0
when it goes left, adds #\1
when it goes right...) and returns these values in pairs of the symbol at a leaf along with its associated encoding as a string over the characters #\0
and #\1
. Similar to what this or this is trying to do.
My original code:
(define (last l)
(car (reverse l)))
(define (codeWords t)
(define (helper t l)
(cond ((null? t) l)
((eq? (car t) 'internal) (append (helper (caddr t) l)
(helper (last t) l)))
((eq? (car t) 'leaf) (helper '() (cons (cons (caddr t) (cadr t)) l)))))
(helper t '()))
(codeWords (huffman (get-freq (get-count "hello"))))
I revamped it after a friend's suggestion but my leaf?
function is getting an error:
(mcar: contract violation
expected: mpair?
given: 1):
(define (leaf? T) (eq? (car T) 'leaf))
(define (subtree T c)
(cond ((eq? c #\0) (cadr T))
((eq? c #\1) (caddr T))))
(define (codeWords t)
(define (helper x y)
(if (leaf? x)
(list (cons (value x) (reverse y)))
(append (helper (subtree x #\0)
(cons #\0 y))
(helper (subtree x #\1)
(cons #\1 y)))))
(helper t '()))
I also came up with this code, which seems like it can work but its not passing my test cases:
(define (codeWords t)
(define (encode char tree)
(cond
((null? tree) t)
((eq? (caar tree) char) '())
(else
(let ((left (encode char (cadr tree))) (right (encode char (caddr tree))))
(cond
((not (or left right)) #f)
(left (cons #\0 left))
(right (cons #\1 right)))))))
(encode t '()))
I am thinking there is probably a solution without having to make a leaf?
function by using eq?
and 'leaf
like in my original code or trying to implement something like the encode function here, but I'm currently having writers block.