Particiones primas
Una partición prima de un número natural n es un conjunto de primos cuya suma es n. Por ejemplo, el número 7 tiene 7 particiones primas ya que
7 = 7 = 5 + 2 = 3 + 2 + 2
Definir la función
particiones :: Int -> [[Int]]
tal que (particiones n) es el comjunto de las particiones primas de n. Por ejemplo,
particiones 7 == [[7],[5,2],[3,2,2]] particiones 8 == [[5,3],[3,3,2],[2,2,2,2]] particiones 9 == [[7,2],[5,2,2],[3,3,3],[3,2,2,2]] length (particiones 100) == 40899
Soluciones
import Data.Numbers.Primes (primes) import Data.Array (Array, (!), array) -- 1ª solución -- =========== particiones1 :: Int -> [[Int]] particiones1 0 = [[]] particiones1 n = [x:y | x <- xs, y <- particiones1 (n-x), [x] >= take 1 y] where xs = reverse (takeWhile (<= n) primes) -- 2ª solución (con programación dinámica) -- ======================================= particiones2 :: Int -> [[Int]] particiones2 n = (vectorParticiones n) ! n -- (vectorParticiones n) es el vector con índices de 0 a n tal que el -- valor del índice k es la lista de las particiones primas de k. Por -- ejemplo, -- λ> mapM_ print (elems (vectorParticiones 9)) -- [[]] -- [] -- [[2]] -- [[3]] -- [[2,2]] -- [[5],[3,2]] -- [[3,3],[2,2,2]] -- [[7],[5,2],[3,2,2]] -- [[5,3],[3,3,2],[2,2,2,2]] -- [[7,2],[5,2,2],[3,3,3],[3,2,2,2]] -- λ> elems (vectorParticiones 9) == map particiones1 [0..9] -- True vectorParticiones :: Int -> Array Int [[Int]] vectorParticiones n = v where v = array (0,n) [(i,f i) | i <- [0..n]] where f 0 = [[]] f m = [x:y | x <- xs, y <- v ! (m-x), [x] >= take 1 y] where xs = reverse (takeWhile (<= m) primes) -- Comparación de eficiencia -- ========================= -- λ> length (particiones1 35) -- 175 -- (5.88 secs, 2,264,266,040 bytes) -- λ> length (particiones2 35) -- 175 -- (0.02 secs, 1,521,560 bytes)