Partition an integer x into n primes: Difference between revisions
Content added Content deleted
(Added Prolog Solution) |
m (→{{header|Haskell}}: Used Data.Numbers.Primes, tidied.) |
||
Line 608: | Line 608: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
<lang haskell> |
<lang haskell>import Data.Bool (bool) |
||
import Data.Numbers.Primes |
|||
import Data.List (delete, intercalate) |
import Data.List (delete, intercalate) |
||
-------------------- PRIME PARTITIONS --------------------- |
|||
partition :: Int -> Int -> [Int] |
partition :: Int -> Int -> [Int] |
||
partition x n |
partition x n |
||
| n <= 1 = |
| n <= 1 = |
||
[ x |
[ x |
||
| |
| x == last ps ] |
||
| otherwise = |
| otherwise = go ps x n |
||
where |
where |
||
ps = takeWhile (<= x) primes |
ps = takeWhile (<= x) primes |
||
go ps_ x 1 = |
|||
[ x |
[ x |
||
| x `elem` ps_ ] |
| x `elem` ps_ ] |
||
go ps_ x n = |
|||
let found = foldMap partitionsFound ps_ |
let found = foldMap partitionsFound ps_ |
||
in |
in bool (head found) [] (null found) |
||
where |
where |
||
partitionsFound p = |
partitionsFound p = |
||
let r = x - p |
let r = x - p |
||
rs = |
rs = go (delete p (takeWhile (<= r) ps_)) r (n - 1) |
||
in |
in bool [p : rs] [] (null rs) |
||
-------------------------- TEST --------------------------- |
|||
main :: IO () |
main :: IO () |
||
main = |
main = |
||
mapM_ putStrLn $ |
mapM_ putStrLn $ |
||
(\(x, n) -> |
(\(x, n) -> |
||
intercalate |
|||
" -> " |
|||
[ justifyLeft 9 ' ' (show (x, n)) |
|||
, let xs = partition x n |
|||
in bool (intercalate "+" (show <$> xs)) "(no solution)" (null xs) |
|||
]) <$> |
|||
concat |
concat |
||
[ [(99809, 1), (18, 2), (19, 3), (20, 4), (2017, 24)] |
[ [(99809, 1), (18, 2), (19, 3), (20, 4), (2017, 24)] |
||
, ( |
, (,) 22699 <$> [1 .. 4] |
||
, [(40355, 3)] |
, [(40355, 3)] |
||
] |
] |
||
------------------------- GENERIC ------------------------- |
|||
justifyLeft :: Int -> Char -> String -> String |
justifyLeft :: Int -> Char -> String -> String |
||
justifyLeft n c s = take n (s ++ replicate n c) |
justifyLeft n c s = take n (s ++ replicate n c)</lang> |
||
nullOr |
|||
:: Foldable t1 |
|||
=> t1 a -> t -> t -> t |
|||
nullOr expression nullValue orValue = |
|||
if null expression |
|||
then nullValue |
|||
else orValue |
|||
primes :: [Int] |
|||
primes = |
|||
2 : |
|||
pruned |
|||
[3 ..] |
|||
(listUnion |
|||
[ (p *) <$> [p ..] |
|||
| p <- primes ]) |
|||
where |
|||
pruned :: [Int] -> [Int] -> [Int] |
|||
pruned (x:xs) (y:ys) |
|||
| x < y = x : pruned xs (y : ys) |
|||
| x == y = pruned xs ys |
|||
| x > y = pruned (x : xs) ys |
|||
listUnion :: [[Int]] -> [Int] |
|||
listUnion = foldr union [] |
|||
where |
|||
union (x:xs) ys = x : union_ xs ys |
|||
union_ (x:xs) (y:ys) |
|||
| x < y = x : union_ xs (y : ys) |
|||
| x == y = x : union_ xs ys |
|||
| x > y = y : union_ (x : xs) ys</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre>(99809,1) -> 99809 |
<pre>(99809,1) -> 99809 |