Two Word Games
October 9, 2012
We begin by creating a framework that reads a dictionary file and displays those words that meet the parameterized requirement; we’ll be able to use that for both games:
(define (game filter)
(for-each-input (filter-input read-line filter)
(lambda (word) (display word) (newline))
"Desktop/moby.words"))
This is simple because the Standard Prelude provides functions for handling file input: for-each-input
processes each line in Desktop/moby.words
and prints it with the lambda
if it passes the filter. Filter-input
is a higher-order function; it takes a reader function (here we use read-line
from the Standard Prelude) and a filter function and returns a new filter function for use by for-each-input
.
With that out of the way, we look at the problem of finding words with five vowels in order:
(define vowels '(#\a #\e #\i #\o #\u))
(define (vowel? c) (member c vowels))
(define (five-vowels-in-order? str)
(equal? vowels (filter vowel? (string->list str))))
We wrote it in three pieces, because it seems more natural that way, but you could easily write it all in one function. Here’s the output:
> (game five-vowels-in-order?)
abstemious
abstemiously
abstentious
acheilous
acheirous
acleistous
affectious
aleikoum
anemious
annelidous
arsenious
arterious
bacterious
caesious
facetious
facetiously
fracedinous
majestious
parecious
pareciously
tragedious
The second game is equally simple:
(define (sorted-and-six? str)
(and (<= 6 (string-length str))
(sorted? char<? (string-%gt;list str))))
The sorted?
function is useful in a variety of situations, and probably ought to be in our Standard Prelude. In fact, I thought it was, and wrote the sorted-and-six?
function assuming that sorted? was already defined, only to be surprised when it didn’t work; maybe I’ll add sorted?
later. You can see sorted?
, along with the rest of the program, at http://programmingpraxis.codepad.org/MDR7xq81. Here’s the output:
> (game sorted-and-six?)
abdest
abhors
acknow
adempt
adhort
adipsy
aegilops
agnosy
almost
anopsy
befist
begins
begirt
behint
beknot
beknow
bijoux
biopsy
cestuy
chimps
chinos
chintz
deflow
deflux
deglory
dehors
dehort
deinos
dhikrs
diluvy
dimpsy
egilops
ghosty
I’ll need to fetch my dictionary to find out what some of those words mean. Everybody use aegilops in a sentence sometime this week!
[…] today’s Programming Praxis exercise, our goal is to find all the words in a dictionary that satisfy two […]
My Haskell solution (see http://bonsaicode.wordpress.com/2012/10/09/programming-praxis-two-word-games/ for a version with comments):
public class WordGame1
{
public List Execute()
{
string line;
var results = new List();
var file = LoadFile();
while ((line = file.ReadLine()) != null)
{
if (ContainsAllFiveVowels(line))
results.Add(line);
}
return results;
}
private static StreamReader LoadFile()
{
var assembly = Assembly.GetExecutingAssembly();
return new StreamReader(assembly.GetManifestResourceStream(“ProgrammingPraxis.Content.354984si.ngl”));
}
private static bool ContainsAllFiveVowels(string textString)
{
return Vowels.All(vow => textString.IndexOf(vow, StringComparison.CurrentCultureIgnoreCase) >= 0);
}
private static IEnumerable Vowels
{
get { return new List {“a”, “e”, “i”, “o”, “u”}; }
}
}
[…] day, another post from Programming Praxis. Today they posted a word game that seems simple enough: first find all […]
That was fun. Most of the work went into loading the file and iterating through them line by line (I miss Python’s
for line in open(filename, 'r'):
), but the rest was pretty straight forward.My solution in Racket / Scheme
A Python solution:
OK, those are great. But of course you can take a low-tech approach to word games, like here: http://daisybrain.wordpress.com/2012/03/09/wordarchy/