#| Spelling Bee solver in Racket. Solver for NY Times Spelling Bee problems: https://www.nytimes.com/puzzles/spelling-bee Which words can be matched given the 7 letters and a center letter? Example: center = 'o', letters = "odteuqn", letters: odteuqn center: o wordlist: words_alpha.txt Number of words in word list: 370105 Accepted words: (dedo denote denoted deuton dodd dodded dode dodo done donee donet donn donne donned donnee donnot dont donut doon dote doted doto dotted dout duetto dunno duodene duotone duotoned eddo endnote endoute enode entone eton neon neoned nodded node noded nondo none nonene nonent nonet nonetto nontoned nontuned noon nooned note noted noun odeon oenone onto oont oooo ottetto otto oudenodon oudenodont outdo outdone outed outen outqueen outquote outquoted quod quodded quot quote quoted quotee quott tendo tendon tenno tenon tenoned tenuto teton teuton todd tode toed toetoe tondo tone toned tonette tonn tonne tonto toon toot tooted toque toquet tote toted toto totquot totted totten tout touted tuno tuquoque tutto undenoted undo undon undone undotted unnoted unode unquod unquote unquoted unto untone untoned untotted) Number of accepted words:125 Running with different options: Syntax: racket spelling_bee_solver.rkt letters center [wordlist] This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Racket page: http://www.hakank.org/racket/ |# #lang racket ; Remove duplicate and sort string -> characters (define (sort-remove-duplicates string) (sort (remove-duplicates (string->list string)) char-ci<=?)) ; Ensure that sub only contains letters that are in chars (define (only-contains? sub valid) (andmap (lambda (v) (member v valid)) sub)) ; Run the Spelling be solver (define (spelling-bee-solver wordlist center letters) (let ([anagram (sort-remove-duplicates letters)] ; convert to list of characters [center-char (first (string->list center))] [words (file->lines wordlist)]) (displayln (format "Number of words in word list: ~a" (length words))) (for/list ([word words] #:do [(define a (sort-remove-duplicates word))] #:when (and (>= (string-length word) 4) (member center-char a) (only-contains? a anagram)) ) word ))) ; Regexp approach (slightly faster) (define (spelling-bee-solver-regexp wordlist center letters) (let ([words (file->lines wordlist)]) (displayln (format "Number of words in word list: ~a" (length words))) (for/list ([word words] #:when (and (>= (string-length word) 4) (regexp-match (regexp center) word) (regexp-match (regexp (string-append "^[" letters "]+$")) word)) ) word ))) ; Default values (define center-default "o") ; As a string, converted to a char later (define letters-default "odteuqn") (define wordlist-default "words_alpha.txt") (define (run) (let* ([cla (current-command-line-arguments)] [len (vector-length cla)] [wordlist wordlist-default] [letters letters-default] [center center-default]) (when (> len 0) (if (<= 2 len 3) (begin (set! letters (vector-ref cla 0)) (set! center (vector-ref cla 1)) (when (= len 3) (set! wordlist (vector-ref cla 2))) ) (begin (displayln "Syntax: racket spelling_bee_solver.rkt letters center [wordlist]\n") (exit) ) )) (displayln (format "letters: ~a center: ~a wordlist: ~a" letters center wordlist)) ; (define accepted (spelling-bee-solver wordlist center letters)) ; Slightly faster (define accepted (spelling-bee-solver-regexp wordlist center letters)) (displayln (format "Accepted words:\n~a" accepted)) (displayln (format "Number of accepted words:~a" (length accepted))) )) (run)