Problem 78 (two solutions ― 78 uses recursion and takes too long, 78_alt uses a recursive function for the partition function that relies on generalized pentagonal numbers); Problem 79 done by hand.
This commit is contained in:
parent
29716fee83
commit
546d8f5ffe
|
@ -0,0 +1,30 @@
|
|||
import qualified Data.IntMap.Strict as M
|
||||
|
||||
filterSum :: Int -> M.IntMap Int -> Int
|
||||
filterSum n subMap =
|
||||
let filterMap = M.filterWithKey (\k _ -> k <= n) subMap
|
||||
in M.foldr (+) 0 filterMap
|
||||
|
||||
getSubmap :: Int -> M.IntMap (M.IntMap Int) -> M.IntMap Int
|
||||
getSubmap k numMap = M.findWithDefault undefined k numMap
|
||||
|
||||
insertSubmap :: Int -> M.IntMap (M.IntMap Int) -> M.IntMap (M.IntMap Int)
|
||||
insertSubmap n numMap=
|
||||
let getFilterSumInsert k subMap = M.insert k (filterSum k (getSubmap (n-k) numMap)) subMap
|
||||
subMap = foldr getFilterSumInsert M.empty [n, n-1..1]
|
||||
in M.insert n subMap numMap
|
||||
|
||||
addToList :: (M.IntMap (M.IntMap Int), (Int, Int)) -> Int -> (M.IntMap (M.IntMap Int), (Int, Int))
|
||||
addToList (currMap, _) n =
|
||||
let nextMap = insertSubmap n currMap
|
||||
nextVal = filterSum n $ getSubmap n $ nextMap
|
||||
in (nextMap, (n, nextVal))
|
||||
|
||||
createNummap :: [(M.IntMap (M.IntMap Int), (Int, Int))]
|
||||
createNummap =
|
||||
let initialMap = M.fromList [(0, M.fromList [(0, 1)])]
|
||||
in scanl addToList (initialMap, (1, 1)) [1..]
|
||||
|
||||
main = print $
|
||||
let (_, finalVal) = last $ takeWhile (\(_, (_, val)) -> val `mod` 1000000 /= 0) $ createNummap
|
||||
in finalVal
|
|
@ -0,0 +1,25 @@
|
|||
import qualified Data.IntMap.Strict as M
|
||||
|
||||
type Map = M.IntMap Integer
|
||||
type Sign = Integer
|
||||
|
||||
getOrFail :: Int -> Map -> Integer
|
||||
getOrFail n m = M.findWithDefault undefined n m
|
||||
|
||||
pentNumsSign :: [(Int, Sign)]
|
||||
pentNumsSign = map (\n -> ((3 * n * n - n) `div` 2, if (even ((abs n) - 1)) then 1 else -1)) $ concat $ map (\n -> [n, -n]) [1..]
|
||||
|
||||
partition :: Int -> Map -> Map
|
||||
partition n m =
|
||||
let part = sum $ map (\(p, sgn) -> sgn * (getOrFail (n-p) m)) $ takeWhile (\(p, sgn) -> p <= n) pentNumsSign
|
||||
in M.insert n part m
|
||||
|
||||
findPartition :: Int -> Map -> Int
|
||||
findPartition n m =
|
||||
let newM = partition n m
|
||||
val = getOrFail n newM
|
||||
in if val `mod` 1000000 == 0
|
||||
then n
|
||||
else findPartition (n+1) newM
|
||||
|
||||
main = print $ findPartition 1 $ M.fromList [(0, 1)]
|
|
@ -0,0 +1,9 @@
|
|||
Did this one by hand: 73162890
|
||||
|
||||
Algorithm:
|
||||
For each three-digit sequence jkl,
|
||||
If there's no path from j to k or k to l,
|
||||
Draw such a directed edge from j to k or k to l
|
||||
If there's more than one path from any m to n
|
||||
Remove all paths except for the longest
|
||||
The result should be a linear acyclic chain
|
Loading…
Reference in New Issue