#!/usr/bin/runhugs -98 module Main where -- from task: http://wwwipd.ira.uka.de/~prechelt/Biblio/jccpprtTR.pdf -- (in my db it is called an-empirical-comparaison-of-c-....pdf) -- 10min comprehension -- 1h10 first version, work for 2 tests -- 10 min fix, (case 'Tor 4' not handle cos bool expr in depth not good) work for example given -- 15 min optimisation (1min find one, 9 think how do better haskell (fail), 5 code first idea) -- 31 lines of code for naive -- 42 for optimised import qualified Prelude as Q import Common type Dictionnary = [(String,[Int])] --opt: type Dictionnary = AssocDefault Int [(String,[Int])] phonecode :: Dictionnary -> String -> (String,[[String]]) phonecode dict s = (s,res) where s' = s.filter isDigit (is::[Int]) = s'.map (\c -> read [c]) res = breath [([],is)] depth (done,todo@(x:xs)) = let goods = dict.{- opt (!x). -}filter (\ (s,ints) -> ints.length <= todo.length && ints == todo.take (ints.length)) in if goods == [] && ((done.length > 0 && ((done.last.length /= 1) || (not (done.last.last.isDigit))) ) || (done.length == 0) ) then [(done++[x.show], xs)] else goods.map (\(s,ints) -> (done++[s], todo.drop (ints.length))) breath [] = [] breath ((done,[]):xs) = done:(breath xs) breath ((done,todo):xs) = breath ((depth (done,todo))++xs) encode :: [String] -> Dictionnary encode dict = dict.map (\s -> (s, s.filter isAlpha.downcase.code)){- opt .sort_dict -} where code s = s.map (\c -> mapping.findIndex (c `elem`).just) mapping = ["e", "jnq", "rwx", "dsy", "ft", "am","civ", "bku", "lop", "ghz"] -- call it with $aryx> phonecode.hs dictionnaryfile numbersfile main = let [fdict,ftests] = argv in do dict <- cat fdict tests <- cat ftests tests.map (phonecode (encode dict)) .mapM(\(number, possibles) -> possibles.mapM(\words -> putStrLn (number^": "^(words.unwords)))) return () {- opt -} -- Optimisations -- sort the dict by first number, if todo = 3:... then we could just filter the dict that start with encoded = 3 -- could to multilevel sorted sort_dict dict = dict.foldl (\z (s, (x:xs)) -> z.update x (insert (s,(x:xs)))) empty ----------------------- dict = ["an","blau","Bo\"","Boot","bo\"s","da","Fee","Fern","Fest","fort","je","jemand","mir","Mix","Mixer","Name","Neu","o\"d","Ort","so","Tor","Torf","Wasser"] dict' = encode dict test1 = phonecode dict' "112" test2 = phonecode dict' "5624-82" test3 = phonecode dict' "4824" -- test.w -- -------- -- an -- blau -- Bo" -- Boot -- bo"s -- da -- Fee -- Fern -- Fest -- fort -- je -- jemand -- mir -- Mix -- Mixer -- Name -- Neu -- o"d -- Ort -- so -- Tor -- Torf -- Wasser -- -- test.t -- -------- -- 112 -- 5624-82 -- 4824 -- 0721/608-4067 -- 10/783--5 -- 1078-913-5 -- 381482 -- 04824 -- -- $aryw> phonecode.hs test.w test.t -- 5624-82: Mix Tor -- 5624-82: mir Tor -- 4824: Torf -- 4824: Tor 4 -- 4824: fort -- 10/783--5: Neu o"d 5 -- 10/783--5: je bo"s 5 -- 10/783--5: je Bo" da -- 381482: so 1 Tor -- 04824: 0 Torf -- 04824: 0 Tor 4 -- 04824: 0 fort