1
0
Fork 0

Day 3 finally done!

This commit is contained in:
Jonathan Chan 2017-12-03 23:48:57 -08:00
parent 45e4e78ab3
commit 845fabfc25
1 changed files with 20 additions and 11 deletions

31
3.hs
View File

@ -1,5 +1,4 @@
import qualified Data.Map.Strict as Map import qualified Data.Map as Map
import Debug.Trace
squareRoot :: Floating a => Int -> a squareRoot :: Floating a => Int -> a
squareRoot = sqrt . fromIntegral squareRoot = sqrt . fromIntegral
@ -10,12 +9,12 @@ getLevel n = ceiling $ (squareRoot n - 1) / 2
getDownstairs :: Int -> Int getDownstairs :: Int -> Int
getDownstairs n = getDownstairs n =
let level = getLevel n let level = getLevel n
in 8 * level - 7 + (n - (2 * level - 1) ^ 2) `div` 2 in n - (8 * level - 7 + 2 * ((n - (2 * level - 1) ^ 2) `div` (2 * level)))
type Store = Map.Map Int Int type Store = Map.Map Int Int
getValue :: Int -> Store -> Int getValue :: Int -> Store -> Int
getValue k m = Map.findWithDefault 0 k m getValue k m = Map.findWithDefault undefined k m
computeValue :: Int -> Store -> Store computeValue :: Int -> Store -> Store
computeValue n m = Map.insert n value m computeValue n m = Map.insert n value m
@ -26,19 +25,29 @@ computeValue n m = Map.insert n value m
postDownstairs = getDownstairs (n+1) postDownstairs = getDownstairs (n+1)
lastCorner = (2 * level + 1) ^ 2 lastCorner = (2 * level + 1) ^ 2
firstPost = (2 * level - 1) ^ 2 + 1 firstPost = (2 * level - 1) ^ 2 + 1
corners = map ((+ lastCorner) . (*(2 * level))) [(-1)..(-3)] secondPost = firstPost + 1
pre = map (1-) corners corners = map ((+ lastCorner) . (*(2 * level))) [(-3)..(-1)]
post = map (1+) (lastCorner:corners) pre = map (+(-1)) corners
post = map (+1) (lastCorner:corners)
value value
| n == firstPost = (n-1) + (getValue postDownstairs m) | n == firstPost = (getValue (n-1) m) + (getValue postDownstairs m)
| n == lastCorner = (getValue (n-1) m) + (getValue preDownstairs m) + (getValue (preDownstairs+1) m) | n == lastCorner = (getValue (n-1) m) + (getValue preDownstairs m) + (getValue (preDownstairs+1) m)
| n `elem` corners = (getValue (n-1) m) + (getValue preDownstairs m) | n `elem` corners = (getValue (n-1) m) + (getValue preDownstairs m)
| n `elem` pre = (getValue (n-1) m) + (getValue (downstairs-1) m) + (getValue downstairs m) | n `elem` pre = (getValue (n-1) m) + (getValue (downstairs-1) m) + (getValue downstairs m)
| n `elem` post = (getValue (n-1) m) + (getValue (n-2) m) + (getValue downstairs m) + (getValue (downstairs+1) m) | n `elem` post ||
n == secondPost = (getValue (n-1) m) + (getValue (n-2) m) + (getValue downstairs m) + (getValue (downstairs+1) m)
| otherwise = (getValue (n-1) m) + (getValue (downstairs-1) m) + (getValue downstairs m) + (getValue (downstairs+1) m) | otherwise = (getValue (n-1) m) + (getValue (downstairs-1) m) + (getValue downstairs m) + (getValue (downstairs+1) m)
computeUntil :: Int -> Int -> Store -> Int
computeUntil max n m =
let newStore = computeValue n m
value = getValue n newStore
in if value < max
then computeUntil max (n+1) newStore
else value
main :: IO () main :: IO ()
main = do main = do
let initialStore = Map.fromList $ zip [1..9] [1, 1, 2, 4, 5, 10, 11, 23, 25] let initialStore = Map.fromList $ zip [1..9] [1, 1, 2, 4, 5, 10, 11, 23, 25]
let infiniStore = foldr computeValue initialStore [10..] print $ computeUntil 368078 10 initialStore
print $ computeValue 10 initialStore