## Programming Praxis – Two Word Games

In today’s Programming Praxis exercise, our goal is to find all the words in a dictionary that satisfy two different criteria. Let’s get started, shall we?

First we have to find the words that have the five vowels in ascending order. To do this we simply check if the vowels in the words are equal to the five vowels in order.

```ascVowels :: String -> Bool
ascVowels = (== "aeiou") . filter (`elem` "aeiou")```

The second game is to find all the six-letter words whose letters are ascending. All we need to check is check the length and whether the first letter of each pair of subsequent letters comes before the second one.

```sixAsc :: Ord b => [b] -> Bool
sixAsc s = length s == 6 && and (zipWith (<) s \$ tail s)```

All that’s left to do is to load the dictionary and print the appropriate words:

```main :: IO ()
main = do ws <- fmap lines \$ readFile "354984si.ngl"
mapM_ putStrLn \$ filter ascVowels ws
putStrLn "---"
mapM_ putStrLn \$ filter sixAsc ws```

### 4 Responses to “Programming Praxis – Two Word Games”

1. What's In a Name? Says:

Which language are you using? I couldn’t recognize any language from the tags

2. Remco Niemeijer Says:

3. treeowl Says:

Your implementation of sixAsc isn’t as efficient as it could be: length s == 6 is not really a good way to check whether the length is six. I would suggest

sixAsc s@[_,_,_,_,_,_] = and (zipWith (<) s \$ tail s)
sixAsc _ = False

but you could also define
lengthis 0 [] = True
lengthis 0 _ = False
lengthis n [] = False
lengthis n (a:as) = lengthis (n-1) as

and use that. The problem with your way is that determining the length of a word is O(n), while determining whether the length of a word is equal to k is only O(k).

4. Remco Niemeijer Says:

You are of course correct. Given that our input is dictionary words, however, the maximum length of a word is limited, maybe 30 characters tops. The average length will probably be somewhere around the six character mark. The difference between O(k) and O(n), therefore, is pretty small. Since performance was neither a focus nor a problem in this exercise I opted for the the solution that is more intuitive and readable, if perhaps slightly less efficient. Replacing a simple but naive implementation when performance becomes an issue is generally easier than quickly figuring out the meaning of an optimized but complex bit of code.