From 6b40eb033d9c0bda4006f23426c34ef8fda4a0d5 Mon Sep 17 00:00:00 2001 From: bd Date: Fri, 24 May 2024 18:21:35 -0600 Subject: Add partial "mutate" implementation, failing tests --- spellcheck/dictionary.scm | 36 +++++++++++++++++++++++++++++++++ spellcheck/hasher/dictionary.scm | 37 ---------------------------------- spellcheck/mutate.scm | 43 ++++++++++++++++++++++++++++++++++++++++ spellcheck/spellcheck-test.scm | 29 ++++++++++++++++++++++++--- 4 files changed, 105 insertions(+), 40 deletions(-) create mode 100644 spellcheck/dictionary.scm delete mode 100644 spellcheck/hasher/dictionary.scm create mode 100644 spellcheck/mutate.scm (limited to 'spellcheck') diff --git a/spellcheck/dictionary.scm b/spellcheck/dictionary.scm new file mode 100644 index 0000000..856fec5 --- /dev/null +++ b/spellcheck/dictionary.scm @@ -0,0 +1,36 @@ +(define-module (dictionary) + #:export (create-dictionary + dict-occur-ref + dict-keys-ref + dict-values-ref)) + +(define (create-dictionary lst) + (dictionary-helper (make-hash-table) lst)) + +(define (dictionary-helper dict rest) + "Recursively adds words to DICT." + (if (null? rest) + dict + (begin + (dict-inc-word dict (car rest)) + (dictionary-helper dict (cdr rest))))) + +(define (dict-inc-word dict e) + "Inserts word E into the DICT, using E +as a key and the running total of occurances +as the value." + (hashq-set! + dict e (1+ (dict-occur-ref dict e)))) + +(define (dict-occur-ref dict e) + "A wrapper for hashq-ref. Returns '0' if an element +is not present, rather than '#f'." + (or (hashq-ref dict e) 0)) + +(define (dict-keys-ref dict) + "Returns a list of all words in the dictionary." + (map car (hash-map->list cons dict))) + +(define (dict-values-ref dict) + "Sums up the total number of occurances for all words." + (apply + (map cdr (hash-map->list cons dict)))) diff --git a/spellcheck/hasher/dictionary.scm b/spellcheck/hasher/dictionary.scm deleted file mode 100644 index 10ec3b8..0000000 --- a/spellcheck/hasher/dictionary.scm +++ /dev/null @@ -1,37 +0,0 @@ -(define-module (hasher dictionary) - #:export (create-dictionary - dict-occur-ref - dict-keys-ref - dict-values-ref)) - -(define (create-dictionary lst) - (dictionary-helper (make-hash-table) lst)) - -(define (dictionary-helper dict rest) - "Recursively adds words to DICT." - (if (null? rest) - dict - (begin - (dict-inc-word dict (car rest)) - (dictionary-helper dict (cdr rest))))) - -(define (dict-inc-word dict e) - "Inserts word E into the DICT, using E -as a key and the running total of occurances -as the value." - (hashq-set! - dict e (1+ (dict-occur-ref dict e)))) - -(define (dict-occur-ref dict e) - "A wrapper for hashq-ref. Returns '0' if an element -is not present, rather than '#f'." - (let ((occur (hashq-ref dict e))) - (if occur occur 0))) - -(define (dict-keys-ref dict) - "Returns a list of all words in the dictionary." - (map car (hash-map->list cons dict))) - -(define (dict-values-ref dict) - "Sums up the total number of occurances for all words." - (apply + (map cdr (hash-map->list cons dict)))) diff --git a/spellcheck/mutate.scm b/spellcheck/mutate.scm new file mode 100644 index 0000000..117d0b3 --- /dev/null +++ b/spellcheck/mutate.scm @@ -0,0 +1,43 @@ +(define-module (mutate) + #:use-module (srfi srfi-1) + #:export (deletes + transposes + replaces + inserts)) + + +;; see https://norvig.com/spell-correct.html +;; this is a translation of that from python +;; to guile +(define (deletes word) + (define (deletes-helper word splits result) + (if (null? splits) + result + (let* ((split (car splits)) + (tail (cdr split))) + (if (zero? (string-length tail)) + (deletes-helper word (cdr splits) result) + (deletes-helper word (cdr splits) + (append result + (list (string-append (car split) (substring tail 1))))))))) + (deletes-helper word (splits word) '())) + +(define (transposes word) + #t) + +(define (replaces word) + #t) + +(define (inserts word) + #t) + + +(define (splits word) + "Given WORD, returns a list of pairs of +all possible splits: + +'six' -> +(('' . 'six') ('s' . 'ix') ('si' . 'x') ('six' . ''))" + (map (lambda (s) (cons (substring word 0 s) + (substring word s))) + (iota (1+ (string-length word))))) diff --git a/spellcheck/spellcheck-test.scm b/spellcheck/spellcheck-test.scm index 8030c41..438384d 100644 --- a/spellcheck/spellcheck-test.scm +++ b/spellcheck/spellcheck-test.scm @@ -1,5 +1,6 @@ (use-modules (srfi srfi-64) - (hasher dictionary)) + (dictionary) + (mutate)) (define simple-dict (create-dictionary '("word"))) (define complex-dict (create-dictionary '("Again" "the" "thirst" @@ -11,7 +12,7 @@ "heart" "of" "the" "snake" "across" "the" "fire"))) -(test-begin "harness") +(test-begin "dictionary") (test-assert "create-dictionary returns hashtable" @@ -54,4 +55,26 @@ (dict-values-ref complex-dict)) -(test-end "harness") +(test-end "dictionary") + +(test-begin "mutate") + + +(test-equal "test deletes six" + '("ix" "sx" "si") + (deletes "six")) + +(test-equal "test transposes" + '("isx" "sxi") + (transposes "six")) + +(test-equal "test replaces" + '("aix" "bix" "cix" "dix" "eix" "fix" "gix" "hix" "iix" "jix" "kix" "lix" "mix" "nix" "oix" "pix" "qix" "rix" "six" "tix" "uix" "vix" "wix" "xix" "yix" "zix" "sax" "sbx" "scx" "sdx" "sex" "sfx" "sgx" "shx" "six" "sjx" "skx" "slx" "smx" "snx" "sox" "spx" "sqx" "srx" "ssx" "stx" "sux" "svx" "swx" "sxx" "syx" "szx" "sia" "sib" "sic" "sid" "sie" "sif" "sig" "sih" "sii" "sij" "sik" "sil" "sim" "sin" "sio" "sip" "siq" "sir" "sis" "sit" "siu" "siv" "siw" "six" "siy" "siz") + (replaces "six")) + +(test-equal "test inserts" + '("asix" "bsix" "csix" "dsix" "esix" "fsix" "gsix" "hsix" "isix" "jsix" "ksix" "lsix" "msix" "nsix" "osix" "psix" "qsix" "rsix" "ssix" "tsix" "usix" "vsix" "wsix" "xsix" "ysix" "zsix" "saix" "sbix" "scix" "sdix" "seix" "sfix" "sgix" "shix" "siix" "sjix" "skix" "slix" "smix" "snix" "soix" "spix" "sqix" "srix" "ssix" "stix" "suix" "svix" "swix" "sxix" "syix" "szix" "siax" "sibx" "sicx" "sidx" "siex" "sifx" "sigx" "sihx" "siix" "sijx" "sikx" "silx" "simx" "sinx" "siox" "sipx" "siqx" "sirx" "sisx" "sitx" "siux" "sivx" "siwx" "sixx" "siyx" "sizx" "sixa" "sixb" "sixc" "sixd" "sixe" "sixf" "sixg" "sixh" "sixi" "sixj" "sixk" "sixl" "sixm" "sixn" "sixo" "sixp" "sixq" "sixr" "sixs" "sixt" "sixu" "sixv" "sixw" "sixx" "sixy" "sixz") + (inserts "six")) + + +(test-end "mutate") -- cgit v1.2.3