summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--11-2.hs53
1 files changed, 53 insertions, 0 deletions
diff --git a/11-2.hs b/11-2.hs
new file mode 100644
index 0000000..d6c61aa
--- /dev/null
+++ b/11-2.hs
@@ -0,0 +1,53 @@
+import Data.Array
+import Data.HashMap.Strict (HashMap, fromListWith, toList)
+
+transform :: Int -> Either Int (Int,Int)
+transform n
+ | even (digits n) = Right $ halves n
+ | otherwise = Left $ n * 2024
+
+digits :: Int -> Int
+digits n = floor $ logBase 10 (fromIntegral n) + 1
+
+halves :: Int -> (Int,Int)
+halves n = ( floor $ fromIntegral n / 10^x
+ , n `mod` 10^x
+ )
+ where
+ x = digits n `div` 2
+
+next :: Array Int (Either Int (Int,Int))
+next = array (0, maxIdx)
+ $ (0, Left 1) : [ (n, transform n) | n <- [1..maxIdx] ]
+
+maxIdx :: Int
+maxIdx = 10^4
+
+getNext :: Int -> Either Int (Int,Int)
+getNext x | x <= maxIdx = next ! x
+ | otherwise = transform x
+
+depth :: Int
+depth = 75
+
+evalList :: [(Int,Int)] -> [(Int,Int)]
+evalList = go []
+ where
+ go :: [(Int,Int)] -> [(Int,Int)] -> [(Int,Int)]
+ go res [] = res
+ go res ((x,c):xs) = case getNext x of
+ Left y -> go ((y,c):res) xs
+ Right (y,z) -> go ((y,c):(z,c):res) xs
+
+evalHM :: HashMap Int Int -> HashMap Int Int
+evalHM = fromListWith (+) . evalList . toList
+
+main :: IO ()
+main = getLine
+ >>= print
+ . sum
+ . (!! depth)
+ . iterate evalHM
+ . fromListWith (+)
+ . map ((,1) . read)
+ . words