Untitled
unknown
haskell
4 years ago
3.2 kB
6
Indexable
module Ch11.Phone where import Data.Char (toLower, isUpper) import Data.List (group, sort) import Ch11.Adt (splitWords) data Key = One | Star | TextKey Char [Char] instance Show Key where show One = "1" show Star = "*" show (TextKey c _) = c : "" type Phone = [Key] phoneKb :: Phone phoneKb = [One, Star, TextKey '#' ".,", TextKey '2' "abc", TextKey '3' "def", TextKey '4' "ghi" , TextKey '5' "jkl", TextKey '6' "mno", TextKey '7' "pqrs" , TextKey '8' "tuv", TextKey '9' "wxyz", TextKey '0' "+ _" ] type Presses = Int -- function names are retarded, I kept the ones from the book -- calculate key sequence to press to reach to given character reverseTaps :: Phone -> Char -> [(Key, Presses)] reverseTaps kb c | isUpper c = (Star, 1) : [(letterPresses kb $ toLower c)] | otherwise = [letterPresses kb c] -- guaranteed to be lowercase letterPresses :: Phone -> Char -> (Key, Presses) letterPresses kb c = case find (matchSeq c) $ concat $ map charSeqs kb of -- function is not complete, but this is what exercise signature wants to Nothing -> error "invalid character" Just (k, _, n) -> (k, n) find :: (a -> Bool) -> [a] -> Maybe a find _ [] = Nothing find p (x:xs) | p x = Just x | otherwise = find p xs -- matches given character with given keypress sequence, -- return True if the char in the seq is the same as given char matchSeq :: Char -> (Key, Char, Presses) -> Bool matchSeq c (_, c', _) = c == c' -- all possible tap sequences for a given key, resulting in different characters -- each tuple is: (k, c, n) where k is key to press, c is character that -- will result from it and n is a number of presses required charSeqs :: Key -> [(Key, Char, Presses)] charSeqs One = [] charSeqs Star = [] charSeqs k@(TextKey digit letters) = zip3 (repeat k) allLetters presses where allLetters = letters ++ [digit] presses = [1..(length allLetters)] -- calculate key sequence to press to print given string cellPhonesDead :: Phone -> String -> [(Key, Presses)] cellPhonesDead kb s = concat $ map (reverseTaps kb) s -- get total number of taps in a sequence fingerTaps :: [(Key, Presses)] -> Presses fingerTaps ks = foldr (+) 0 $ map snd ks -- most frequent letter in a string mostPopularLetter :: String -> Char mostPopularLetter "" = error "empty string" mostPopularLetter s = findMostFrequent s findMostFrequent :: Ord a => [a] -> a findMostFrequent [] = error "empty list" findMostFrequent xs@(x:_) = snd $ foldr max (1, x) freqs where freq cs = (length cs, head cs) freqs = map freq $ group $ sort xs -- most frequent letter in a list of strings coolestLetter :: [String] -> Char coolestLetter ss = mostPopularLetter $ concat ss -- most frequent word in a list of strings coolestWord :: [String] -> String coolestWord ss = findMostFrequent totalWords where totalWords = concat $ map splitWords ss convo :: [String] convo = ["Wanna play 20 questions", "Ya", "U 1st haha", "Lol ok. Have u ever tasted alcohol", "Lol ya", "Wow ur cool haha. Ur turn", "Ok. Do u think I am pretty Lol", "Lol ya", "Just making sure rofl ur turn"]
Editor is loading...