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
Tags: ascending, bonsai, code, games, Haskell, kata, praxis, programming, vowels, word
October 9, 2012 at 9:45 pm |
Which language are you using? I couldn’t recognize any language from the tags
October 9, 2012 at 9:47 pm |
The language is called Haskell. You can find out more about it here: http://www.haskell.org/haskellwiki/Haskell
October 10, 2012 at 11:38 am |
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).
October 10, 2012 at 1:37 pm |
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.