learning-sicp

My embarrassing half assed SICP run.
Log | Files | Refs

commit 8aa798ee1b197160c1069642aaa45946ab410601
parent 003b86c2d451d4fff198dc983ea584bd2798ced9
Author: Yuval Langer <yuval.langer@gmail.com>
Date:   Tue, 28 Mar 2023 11:38:33 +0300

Add solution to exercise 2.70 and gitignore and makefile stuff.

Diffstat:
M.gitignore | 6++++--
MMakefile | 6++++++
Msicp/solutions/huffman-codes-stuff.scm | 7+++++--
Asicp/tests/2.70.scm | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,4 +1,6 @@ *.log -*.scm~ -*\#* *.scm.* +*\#* +*~ +moo.* +poop.* diff --git a/Makefile b/Makefile @@ -1,3 +1,9 @@ +poop: + echo poop + +2.70: + guile -l sicp/utils.scm -l sicp/solutions/exercise-1.21.scm -l sicp/solutions/exercise-2.40.scm -l sicp/solutions/huffman-codes-stuff.scm sicp/tests/2.70.scm + tests: guile.scm guile --no-auto-compile guile.scm diff --git a/sicp/solutions/huffman-codes-stuff.scm b/sicp/solutions/huffman-codes-stuff.scm @@ -5,11 +5,14 @@ (import (scheme cxr)) (import (only (sicp utils) accumulate)) (import (only (sicp solutions exercise-2.40) remove)) - (export make-code-tree + (export decode + encode + generate-huffman-tree make-leaf sample-message sample-tree - generate-huffman-tree) + weight + make-code-tree) (begin (define (make-leaf symbol weight) diff --git a/sicp/tests/2.70.scm b/sicp/tests/2.70.scm @@ -0,0 +1,84 @@ +(import (srfi :26)) +(import (srfi :64)) +(import (only (sicp utils) accumulate)) +(import (only (sicp solutions huffman-codes-stuff) + decode + encode + generate-huffman-tree + weight + make-leaf)) + +(define (remove-empty-strings list-of-strings) + (filter (compose not + (cut equal? + "" + <>)) + list-of-strings)) + +(define code-text + "A 2 NA 16 +BOOM 1 SHA 3 +GET 2 YIP 9 +JOB 2 WAH 1") + +(define songs-huffman-tree + (let* ([split-code-text + (string-split code-text + (string->char-set "\n "))] + [only-tokens-code-text + (remove-empty-strings split-code-text)] + [list-of-pairs (let loop ([code-list only-tokens-code-text]) + (cond + ((null? code-list) '()) + ((null? (cdr code-list)) '()) + (else (cons (list (string->symbol (car code-list)) + (string->number (cadr code-list))) + (loop (cddr code-list))))))] + [ordered-pairs-by-weight (sort list-of-pairs + (lambda (x y) + (< (cadr x) + (cadr y))))]) + (generate-huffman-tree ordered-pairs-by-weight))) + +(define song-text + "Get a job +Sha na na na na na na na na + +Get a job +Sha na na na na na na na na + +Wah yip yip yip yip +yip yip yip yip yip +Sha boom") + +(define only-letters-song-message + (remove-empty-strings + (string-split (string-upcase song-text) + (string->char-set "\n ")))) + +(define song-message + (map string->symbol only-letters-song-message)) + +(define encoded-song-message + (encode song-message + songs-huffman-tree)) + +(test-begin "2.70") +(test-equal + 84 + (length encoded-song-message)) +(test-equal + 992 + (* 8 ;; Length of message in bits is a 8 bits per byte times length of message in characters. + (apply + ;; length of message in characters + (cons ;; is length of spaces + (- (length only-letters-song-message) ;; which is the length of message in symbols + 1) ;; minus one to get the number of spaces between symbols + (map string-length + only-letters-song-message))))) ;; plus the number of characters in each symbol. +(test-end "2.70") + +;; We count consecutive whitespaces - newline and a spacey space - as a single +;; space delimiting the symbols. +;; We also disregard letter case and casing, which is unadvised for a +;; reasonably safe journey in the land of languages.