Skip to content

Instantly share code, notes, and snippets.

@uskudnik
Created June 26, 2017 20:35
Show Gist options
  • Save uskudnik/b5c420c39aa225dd7ce69dc34806c88f to your computer and use it in GitHub Desktop.
Save uskudnik/b5c420c39aa225dd7ce69dc34806c88f to your computer and use it in GitHub Desktop.
smsing like in the old days
import Data.Char
import Data.List
import Data.Map (Map)
import qualified Data.Map.Strict as Map
{-|
---------------------------
| 1 | 2 ABC | 3 DEF |
___________________________
| 4 GHI | 5 JKL | 6 MNO |
---------------------------
| 7 PQRS | 8 TUV | 9 WXYZ |
---------------------------
| * ^ | 0 + _ | # ., |
---------------------------
-}
type Digit = Char
type Presses = Int
type Key = Char
type Chars = String
data DaPhone = DaPhone (Map.Map Key Chars) deriving (Show)
data InverseDaPhone = InverseDaPhone (Map.Map Char Key) deriving (Show)
unpackInverseDaPhone :: InverseDaPhone -> (Map.Map Char Key)
unpackInverseDaPhone (InverseDaPhone mapping) = mapping
phoneToList :: DaPhone -> [(Key, Chars)]
phoneToList (DaPhone kvs) = Map.toList kvs
phoneFromList :: [(Char, String)] -> DaPhone
phoneFromList lst = DaPhone (Map.fromList lst)
inversePhoneFromList :: [(Char, Char)] -> InverseDaPhone
inversePhoneFromList lst = InverseDaPhone (Map.fromList lst)
inversePhone :: DaPhone -> InverseDaPhone
inversePhone phone = inversePhoneFromList $ foldr (++) [] (map (
\(kkey, chars) -> map (
\char -> (char, kkey)) chars) (phoneToList phone))
charsAtKey :: Key -> DaPhone -> Chars
charsAtKey key (DaPhone kvs) =
let
lu = Map.lookup key kvs
in case lu of
Just val -> val
Nothing -> error "well someone didn't validate the data. naughty naughty."
charAtKey :: Char -> DaPhone -> Key
charAtKey char phone =
let
charToKey = inversePhone phone
lu = Map.lookup char $ unpackInverseDaPhone charToKey
in case lu of
Just key -> key
Nothing -> error "well someone didn't validate the data. naughty naughty."
reverseTaps :: DaPhone -> Char -> [(Digit, Presses)]
reverseTaps phone char =
let key = charAtKey char phone
maybeElemIndex = elemIndex char (charsAtKey key phone )
presses = case maybeElemIndex of
Just elemIndex -> elemIndex
Nothing -> error "well that didn't work out as intended mister. invalid char."
in
if isLower char then [('*', 1)] ++ reverseTaps phone (toUpper char)
else [(key, presses)]
cellPhonesDead :: DaPhone -> String -> [(Digit, Presses)]
cellPhonesDead phone text = foldr (++) [] $ map (\x -> reverseTaps phone x) text
keyboardDefinition = [
('1', "1"),
('2', "ABC2"),
('3', "DEF3"),
('4', "GHI4"),
('5', "JKL5"),
('6', "MNO6"),
('7', "PQRS7"),
('8', "TUV8"),
('9', "WXYZ9"),
('*', "*^"),
('0', " +_0"),
('#', "#.,")]
phoneDef = phoneFromList keyboardDefinition
-- example
-- 'a' -> [('2', 1)]
-- 'A' -> [('*', 1), ('2', 1)]
-- test
-- *Main Data.List Data.Maybe> reverseTaps phoneDef 'A'
-- [('2',0)]
-- *Main Data.List Data.Maybe> reverseTaps phoneDef 'a'
-- [('*',1),('2',0)]
-- *Main Data.List Data.Maybe> cellPhonesDead phoneDef "AA"
-- [('2',0),('2',0)]
-- *Main Data.List Data.Maybe> cellPhonesDead phoneDef "aa bb"
-- [('*',1),('2',0),('*',1),('2',0),('0',0),('*',1),('2',1),('*',1),('2',1)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment