diff options
author | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-11 16:24:27 +0100 |
---|---|---|
committer | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-11 16:24:27 +0100 |
commit | 310a752668c80f13803adff665090a868f54b1ab (patch) | |
tree | 428d42037e5283d2b6e1190fe327e442fee47eb2 | |
parent | 109578eaa586a23830c0ae43a9f1418b77a27be1 (diff) | |
download | aoc2024-310a752668c80f13803adff665090a868f54b1ab.tar.gz aoc2024-310a752668c80f13803adff665090a868f54b1ab.zip |
11-2
Sadly did not manage this one without help. Had to look at Reddit to
figure out the trick with the hashmap...
-rw-r--r-- | 11-2.hs | 53 |
1 files changed, 53 insertions, 0 deletions
@@ -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 |