[Haskell-cafe] memoization
Daniel Fischer
daniel.is.fischer at web.de
Sat Sep 5 09:51:45 EDT 2009
Am Samstag 05 September 2009 11:52:50 schrieb staafmeister:
> Hi,
>
> I participating in de google code jam this year and I want to try to use
> haskell. The following
> simple http://code.google.com/codejam/contest/dashboard?c=90101#s=p2
> problem
> would have the beautiful haskell solution.
>
> import Data.MemoTrie
> import Data.Char
> import Data.Word
> import Text.Printf
>
> newtype ModP = ModP Integer deriving Eq
>
> p=10000
>
> instance Show ModP where
> show (ModP x) = printf "%04d" x
>
> instance Num ModP where
> ModP x + ModP y = ModP ((x + y) `mod` p)
> fromInteger x = ModP (x `mod` p)
> ModP x * ModP y = ModP ((x * y) `mod` p)
> abs = undefined
> signum = undefined
>
> solve _ [] = 1::ModP
> solve [] _ = 0::ModP
> solve (hs:ts) t@(ht:tt) | hs==ht = solve ts tt + solve ts t
>
> | otherwise = solve ts t
>
> go (run, line) = "Case #"++show run++": "++show (solve line "welcome to
> code jam")
>
> main = interact $ unlines . map go . zip [1..] . tail . lines
>
>
> Which is unfortunately exponential.
>
> Now in earlier thread I argued for a compiler directive in the lines of {-#
> Memoize function -#},
> but this is not possible (it seems to be trivial to implement though).
Not really. Though a heck of a lot easier than automatic memoisation.
> Now I used memotrie which
> runs hopelessly out of memory. I looked at some other haskell solutions,
> which were all ugly and
> more clumsy compared to simple and concise C code. So it seems to me that
> haskell is very nice
> and beautiful until your are solving real algorithmic problems when you
> want to go back to some
> imperative language.
>
> How would experienced haskellers solve this problem?
>
> Thanks
completely unoptimised:
----------------------------------------------------------------------
module Main (main) where
import Text.Printf
import Data.List
out :: Integer -> String
out n = printf "%04d" (n `mod` 10000)
update :: [(String,Integer)] -> Char -> [(String,Integer)]
update ((p@((h:_),n)):tl) c
= case update tl c of
((x,m):more)
| c == h -> p:(x,m+n):more
other -> p:other
update xs _ = xs
solve pattern = snd . last . foldl' update (zip (tails pattern) (1:repeat 0))
solveLine :: String -> (Integer,String) -> String
solveLine pattern (i,str) = "Case# " ++ show i ++ ": " ++ out (solve pattern str)
main :: IO ()
main = interact $ unlines . map (solveLine "welcome to code jam")
. zip [1 .. ] . tail . lines
----------------------------------------------------------------------
./codeJam +RTS -sstderr -RTS < C-large-practice.in
<snip>
Case# 98: 4048
Case# 99: 8125
Case# 100: 0807
15,022,840 bytes allocated in the heap
789,028 bytes copied during GC
130,212 bytes maximum residency (1 sample(s))
31,972 bytes maximum slop
1 MB total memory in use (0 MB lost due to fragmentation)
Generation 0: 28 collections, 0 parallel, 0.00s, 0.00s elapsed
Generation 1: 1 collections, 0 parallel, 0.00s, 0.00s elapsed
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.04s ( 0.03s elapsed)
GC time 0.00s ( 0.01s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 0.04s ( 0.04s elapsed)
%GC time 0.0% (13.8% elapsed)
Alloc rate 417,277,929 bytes per MUT second
Productivity 100.0% of total user, 98.6% of total elapsed
More information about the Haskell-Cafe
mailing list