-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFastAnagrams.hs
41 lines (33 loc) · 1.12 KB
/
FastAnagrams.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoImplicitPrelude #-}
module FastAnagrams where
import Core
import qualified Data.Char as Ch
import qualified Data.Function as Fn
import qualified Data.Set as S
import qualified Functor as F
import List (Chars, FilePath, List)
import qualified List as L
-- Return all anagrams of the given string
-- that appear in the given dictionary file.
-- on a Mac - run this with:
-- > fastAnagrams "Tony" "/usr/share/dict/words"
fastAnagrams :: Chars -> FilePath -> IO (List Chars)
fastAnagrams s filename =
L.filter isMember . L.lines F.<$> content
where
content = L.readFile filename
anagrams = L.foldLeft (flip (S.insert . NoCaseString)) S.empty (L.permutations s)
isMember = flip S.member anagrams . NoCaseString
newtype NoCaseString
= NoCaseString
Chars
ncString :: NoCaseString -> Chars
ncString (NoCaseString s) = s
instance Eq NoCaseString where
(==) = (==) `on` L.map Ch.toLower . ncString
instance Show NoCaseString where
show = show . ncString
-- Instance of Ord is required to insert in a Set.
instance Ord NoCaseString where
compare = Fn.on compare ncString