Word Cube
July 13, 2010
Our solution is a straight forward statement of the problem:
(define (wordcube puzzle)
(let* ((ltrs (string->list puzzle))
(must (string-ref puzzle 4))
(sign (sort char<? ltrs)))
(with-input-from-file "/usr/share/dict/words"
(lambda ()
(let loop ((word (read-line)) (words '()))
(if (eof-object? word) (reverse words)
(let ((ws (sort char<? (string->list word))))
(if (and (< 3 (length ws))
(member must ws)
(subset? ws sign))
(loop (read-line) (cons word words))
(loop (read-line) words)))))))))
We “sign” each word by sorting its letters into ascending order. Member
assures that the central letter is part of the solution, and subset?
compares two signatures to ensure that the first is a subset of the second:
(define (subset? s1 s2)
(let loop ((s1 s1) (s2 s2))
(cond ((null? s1) #t) ((null? s2) #f)
((char<? (car s1) (car s2)) #f)
((char<? (car s2) (car s1))
(loop s1 (cdr s2)))
(else (loop (cdr s1) (cdr s2))))))
Here’s an example:
> (wordcube "ncbcioune")
("bonnie" "bunion" "coin" "concubine" "conic" "cubic" "ennui" "icon" "nice" "nine" "nuncio" "union")
We used read-line
and sort
from the Standard Prelude. You can see the entire program at http://programmingpraxis.codepad.org/E61ALT0i.
[…] Praxis – Word Cube By Remco Niemeijer In today’s Programming Praxis exercise our task is to write a program to solve Word Cube puzzles, in which you […]
My Haskell solution (see http://bonsaicode.wordpress.com/2010/07/13/programming-praxis-word-cube/ for a version with comments):
Here is my attempt in clojure:
http://pastebin.com/gVf0DZV9
A bit of python:
def words_in_cube(cube):
return filter(lambda word: 3 < len(word) < 10 and \
cube[4] in word and
all(word.count(x) <= cube.count(x) for x in word),
(word.strip() for word in open('/usr/share/dict/words').xreadlines()))
Here’s a version in LUA:
http://pastebin.com/vBeDvup9
@matias: The python version misses the words with upper case characters.
[…] is my first solution for a Programming Praxis assignment, the Word Cube […]
I’d appreciate any well-versed criticism of the regex I used:
@Jebb
The character set match ^[ncbcioune]+$ just validates that your dictionary word only consists of characters from the cube. However, like some of the other answers here, it doesn’t account for the distribution of these characters in the cube and the dictionary word. Therefore, your algorithm gives incorrect answers like “bobbin”, “innocence”, “niece”, and “onion”.
[…] that finds all matching words for a given word cube. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments […]
@ Gary: OK, looks like I’d completely misunderstood the assignment. I’m beginning to suspect regexes are not the right tool here…
[…] in my recent set of Word Games from Programming Praxis, today we’re tasked with finding all words made from a grid of […]
Here’s a version written in Racket that generalizes to any size grid (although the minimum length of 4 is hard-coded) and seems to work pretty well:
Word Cubes