1
0
Fork 0

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:
Jonathan Chan 2017-07-16 11:18:54 -07:00
parent 29716fee83
commit 546d8f5ffe
12 changed files with 64 additions and 0 deletions

BIN
76

Binary file not shown.

BIN
76.hi

Binary file not shown.

BIN
76.o

Binary file not shown.

BIN
78 Executable file

Binary file not shown.

BIN
78.hi Normal file

Binary file not shown.

30
78.hs Normal file
View File

@ -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

BIN
78.o Normal file

Binary file not shown.

BIN
78_alt Executable file

Binary file not shown.

BIN
78_alt.hi Normal file

Binary file not shown.

25
78_alt.hs Normal file
View File

@ -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)]

BIN
78_alt.o Normal file

Binary file not shown.

9
79.txt Normal file
View File

@ -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