Partition function P: Difference between revisions

Content added Content deleted
No edit summary
(→‎{{header|Haskell}}: added solution)
Line 657: Line 657:
Computation time in ms: 26
Computation time in ms: 26
</pre>
</pre>

=={{header|Haskell}}==

<lang haskell>{-# language DeriveFunctor #-}

------------------------------------------------------------
-- memoization utilities

data Memo a = Node a (Memo a) (Memo a)
deriving Functor

memo :: Integral a => Memo p -> a -> p
memo (Node a l r) n
| n == 0 = a
| odd n = memo l (n `div` 2)
| otherwise = memo r (n `div` 2 - 1)

nats :: Memo Int
nats = Node 0 ((+1).(*2) <$> nats) ((*2).(+1) <$> nats)

------------------------------------------------------------
-- calculating partitions

partitions :: Memo Integer
partitions = partitionP <$> nats

partitionP :: Int -> Integer
partitionP n
| n < 2 = 1
| otherwise = sum $ zipWith (*) signs terms
where
terms = [ memo partitions (n - i)
| i <- takeWhile (<= n) ofsets ]
signs = cycle [1,1,-1,-1]

ofsets = scanl1 (+) $ mix [1,3..] [1,2..]
where
mix a b = concat $ zipWith (\x y -> [x,y]) a b

main = print $ partitionP 6666</lang>

<pre>*Main> partitionP <$> [1..10]
[1,2,3,5,7,11,15,22,30,42]

*Main> partitionP 100
190569292

*Main> partitionP 1000
24061467864032622473692149727991

*Main> partitionP 6666
193655306161707661080005073394486091998480950338405932486880600467114423441282418165863</pre>


=={{header|J}}==
=={{header|J}}==