-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetBeeWords.hs
91 lines (71 loc) · 2.44 KB
/
getBeeWords.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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import Data.Maybe
import Data.List
import qualified Data.Map as Map
addNoDupSorted :: Ord a => [a] -> [a] -> a -> [a]
addNoDupSorted pre [] x = pre++[x]
addNoDupSorted pre (y:rest) x = if y == x then pre++(y:rest)
else if y < x then addNoDupSorted (pre++[y]) rest x
else pre ++ (x:y:rest)
addNoDup :: Eq a => [a] -> a -> [a]
addNoDup l x = if (elem x l) then l else x:l
removeDups :: String -> String
removeDups s = foldl (\accum -> \new -> addNoDup accum new) [] s
removeDupsSorted :: String -> String
removeDupsSorted s
= foldl (\acc -> \new -> addNoDupSorted [] acc new) [] s
isBeeWord :: String -> Bool
isBeeWord w =
(length w > 6) && (not (elem 's' w)) && (length (removeDups w) == 7)
wordAndLetters w =
w ++ ": " ++ (removeDupsSorted w)
formatPair (s1, s2) =
s1 ++ ": " ++ s2
beeWord :: String -> Maybe (String, String)
beeWord w =
if length w > 6 && not (elem 's' w)
then
let dedup = removeDupsSorted w
in
if length dedup == 7 then
Just (w, dedup)
else
Nothing
else
Nothing
-- sort a list of pairs by their second elements
-- sortBySecond = sortBy (\(_,a) (_,b) -> compare a b)
-- unnecessary if we use the Data.Map structure, b/c insertion sorts.
swap (a,b) = (b,a)
-- redone in points free style
-- collate list of (k, v) w/duplicate ks into (k, [vs]) map
-- collate kvpairs =
-- let
-- singles = map (\(x,y) -> (x,[y])) kvpairs
-- in
-- Map.fromListWith (++) singles
-- build a map whose keys are bees and values are lists of pangrams
collate = Map.fromListWith (++) . map (\(x,y) -> (x,[y]))
-- pangramMap :: [(pangram, bee)] -> map from bee to all pangrams
pangramMap = collate . map swap
-- turn into (bee, "pangram1, pangram2, etc"]) pairs
mapToBeePangramsList beeWordsMap =
let
beeWordsList = Map.toList beeWordsMap
in
map (\(key, val) -> (key, intercalate ", " val)) beeWordsList
-- Top level function
-- beeLines input = output, where input and output are multi-line file
-- contents, one word per line
beeLines :: String -> String
beeLines input =
let
allLines = lines input
-- matches = filter beeWord allLines
-- formatted = map wordAndLetters matches
matches = mapMaybe beeWord allLines
pangrams = pangramMap matches -- n.b.: hook in here to do more
pangramsList = mapToBeePangramsList pangrams
-- sorted = sortBySecond matches
in -- turn back into a blob of text
unlines (map formatPair pangramsList)
main = interact beeLines