Skip to content

Instantly share code, notes, and snippets.

@rajadain
Created September 5, 2017 20:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rajadain/e7254807503a519523fcb1b8a8f5d6e0 to your computer and use it in GitHub Desktop.
Save rajadain/e7254807503a519523fcb1b8a8f5d6e0 to your computer and use it in GitHub Desktop.
Haskell Book Chapter 11 Exercise: Phone
-- 11-exercise-phone.hs
module ExercisePhone where
import Data.Char
import Data.List
import Data.Maybe
type Key = Char
type Presses = Int
daPhone :: [String]
daPhone = ["abc2","def3","ghi4","jkl5",
"mno6","pqrs7","tuv8","wxyz9",
"+ 0",".,#"]
test :: String
test = "Hello world"
convo :: [String]
convo =
["Wanna play 20 questions",
"Ya",
"U 1st haha",
"Lol ok. Have u ever tasted alcohol lol",
"Lol ya",
"Wow ur cool haha. Ur turn",
"Ok. Do u think I am pretty Lol",
"Lol ya",
"Haha thanks just making sure rofl ur turn"]
reverseTaps :: String -> [Maybe (Key, Presses)]
reverseTaps "" = []
reverseTaps (x:xs)
| isUpper x = Just ('*', 1) : reverseTap (toLower x) : reverseTaps xs
| otherwise = reverseTap x : reverseTaps xs
fingerTaps :: [(Key, Presses)] -> Presses
fingerTaps = sum . (map snd)
tapsInConvo :: [[(Key, Presses)]]
tapsInConvo = map (catMaybes . reverseTaps) convo
-- Result: [[('*',1),('9',1),('2',1),('6',2),('6',2),('2',1),('0',2),('7',1),('5',3),('2',1),('9',3),('0',2),('2',4),('0',3),('0',2),('7',2),('8',2),('3',2),('7',4),('8',1),('4',3),('6',3),('6',2),('7',4)],[('*',1),('9',3),('2',1)],[('*',1),('8',2),('0',2),('7',4),('8',1),('0',2),('4',2),('2',1),('4',2),('2',1)],[('*',1),('5',3),('6',3),('5',3),('0',2),('6',3),('5',2),('#',1),('0',2),('*',1),('4',2),('2',1),('8',3),('3',2),('0',2),('8',2),('0',2),('3',2),('8',3),('3',2),('7',3),('0',2),('8',1),('2',1),('7',4),('8',1),('3',2),('3',1),('0',2),('2',1),('5',3),('2',3),('6',3),('4',2),('6',3),('5',3),('0',2),('5',3),('6',3),('5',3)],[('*',1),('5',3),('6',3),('5',3),('0',2),('9',3),('2',1)],[('*',1),('9',1),('6',3),('9',1),('0',2),('8',2),('7',3),('0',2),('2',3),('6',3),('6',3),('5',3),('0',2),('4',2),('2',1),('4',2),('2',1),('#',1),('0',2),('*',1),('8',2),('7',3),('0',2),('8',1),('8',2),('7',3),('6',2)],[('*',1),('6',3),('5',2),('#',1),('0',2),('*',1),('3',1),('6',3),('0',2),('8',2),('0',2),('8',1),('4',2),('4',3),('6',2),('5',2),('0',2),('*',1),('4',3),('0',2),('2',1),('6',1),('0',2),('7',1),('7',3),('3',2),('8',1),('8',1),('9',3),('0',2),('*',1),('5',3),('6',3),('5',3)],[('*',1),('5',3),('6',3),('5',3),('0',2),('9',3),('2',1)],[('*',1),('4',2),('2',1),('4',2),('2',1),('0',2),('8',1),('4',2),('2',1),('6',2),('5',2),('7',4),('0',2),('5',1),('8',2),('7',4),('8',1),('0',2),('6',1),('2',1),('5',2),('4',3),('6',2),('4',1),('0',2),('7',4),('8',2),('7',3),('3',2),('0',2),('7',3),('6',3),('3',3),('5',3),('0',2),('8',2),('7',3),('0',2),('8',1),('8',2),('7',3),('6',2)]]
fingerTapsInConvo :: [Presses]
fingerTapsInConvo = map fingerTaps tapsInConvo
-- Result: [52,5,18,88,16,54,65,16,87]
-- HELPER METHODS
-- Returns tuple of (Key, Presses) for a given character
reverseTap :: Char -> Maybe (Key, Presses)
reverseTap x = foldr (orElse . (charInString x)) Nothing daPhone
-- Returns first argument if it is Just, else second
orElse :: Maybe a -> Maybe a -> Maybe a
orElse (Just x) _ = Just x
orElse Nothing x = x
-- If character is in string, returns tuple of Key
-- which is the last character in the string, and
-- elemIndex + 1 which is how many Presses it would take
charInString :: Char -> String -> Maybe (Key, Presses)
charInString x s = case elemIndex x s of Just i -> Just (last s, i + 1)
Nothing -> Nothing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment