From c4a57ffd2d31e231dca39f05fa4729e4aa38521c Mon Sep 17 00:00:00 2001 From: Samae Date: Sat, 21 Dec 2024 22:44:59 +0200 Subject: [PATCH] tmp --- .gitignore | 3 +- Main.hs | 7 +++-- flake.nix | 1 + inputs/day11.input | 1 + package.yaml | 7 +++-- src/Day11.hs | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 inputs/day11.input create mode 100644 src/Day11.hs diff --git a/.gitignore b/.gitignore index 1bd6332..03cde98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ result* *.cabal dist-newstyle -*.eventlog +*.eventlog* *.prof *.dot *.pdf +aoc24-debug.* diff --git a/Main.hs b/Main.hs index f96fb48..692accf 100644 --- a/Main.hs +++ b/Main.hs @@ -12,6 +12,7 @@ import Day7 import Day8 import Day9 import Day10 +import Day11 main :: IO () main = do @@ -34,5 +35,7 @@ main = do -- Day8.main -- putStrLn "Day 9" -- Day9.main - putStrLn "Day 10" - Day10.main + -- putStrLn "Day 10" + -- Day10.main + putStrLn "Day 11" + Day11.main diff --git a/flake.nix b/flake.nix index 93a5523..6d8711f 100644 --- a/flake.nix +++ b/flake.nix @@ -28,6 +28,7 @@ ghcid cabal-install fourmolu + eventlog2html ]; # Change the prompt to show that you are in a devShell shellHook = '' diff --git a/inputs/day11.input b/inputs/day11.input new file mode 100644 index 0000000..e034fb6 --- /dev/null +++ b/inputs/day11.input @@ -0,0 +1 @@ +5910927 0 1 47 261223 94788 545 7771 diff --git a/package.yaml b/package.yaml index 1eb715d..611c232 100644 --- a/package.yaml +++ b/package.yaml @@ -1,6 +1,6 @@ name: aoc24 -ghc-options: -Wall -threaded +ghc-options: -Wall -threaded -O2 default-extensions: - OverloadedStrings @@ -25,6 +25,7 @@ dependencies: - unordered-containers - utility-ht - vector + - MemoTrie executables: aoc24: @@ -33,7 +34,7 @@ executables: - aoc24 aoc24-debug: main: Main.hs - ghc-options: -Wall -threaded -rtsopts -prof #-fprof-auto + ghc-options: -Wall -threaded -O2 -rtsopts -prof -auto-all #-fprof-auto dependencies: - aoc24 @@ -50,7 +51,7 @@ library: - Day8 - Day9 - Day10 - # - Day11 + - Day11 # - Day12 # - Day13 # - Day14 diff --git a/src/Day11.hs b/src/Day11.hs new file mode 100644 index 0000000..a3a4d01 --- /dev/null +++ b/src/Day11.hs @@ -0,0 +1,74 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE OverloadedStrings #-} + +module Day11 where + +import Data.Attoparsec.Text (Parser, decimal, parseOnly, sepBy) +import Data.Function (fix) +import qualified Data.Text.IO as T +import Data.Vector (Vector) +import qualified Data.Vector as V +import Debug.Trace + +parseInput :: Parser [Int] +parseInput = decimal `sepBy` " " + +-- 1. If the stone is engraved with the number 0, it is replaced by a stone +-- engraved with the number 1. +-- 2. If the stone is engraved with a number that has an even number of digits, +-- it is replaced by two stones. The left half of the digits are engraved on +-- the new left stone, and the right half of the digits are engraved on the +-- new right stone. (The new numbers don't keep extra leading zeroes: 1000 +-- would become stones 10 and 0.) +-- 3. If none of the other rules apply, the stone is replaced by a new stone; the +-- old stone's number multiplied by 2024 is engraved on the new stone. +applyRule :: Int -> Vector Int +applyRule 0 = whnfElements $ V.singleton 1 +applyRule n + | even leng && n > 9 = + whnfElements $ V.fromList [n `div` 10 ^ half, n `mod` 10 ^ half] + where + half :: Int + half = leng `div` 2 + leng :: Int + leng = ceiling (logBase 10 (fromIntegral n) :: Float) +applyRule n = whnfElements $ V.singleton $ n * 2024 + +whnfElements :: Vector a -> Vector a +whnfElements v = V.foldl' (flip seq) () v `seq` v + +solveA :: Vector Int -> Int +solveA = V.length . curry iterThis 25 + +solveA' :: [Int] -> Int +solveA' = sum . map (lenMemo 25) + +iterThis :: (Int, Vector Int) -> Vector Int +iterThis (0, vx) = vx +iterThis (n, vx) = iterThis (n - 1, whnfElements $ V.concatMap applyRule vx) + +len :: (Int -> Int -> Int) -> Int -> Int -> Int +len _ 0 _ = 1 +len f i x = traceShow i $ sum (fmap (f (i - 1)) (applyRule x)) + +memoize :: (Int -> a) -> (Int -> a) +memoize f = (map f [0 ..] !!) + +lenMemo :: Int -> Int -> Int +lenMemo = fix (memoize . len) + +solveB :: [Int] -> Int +solveB = sum . map (lenMemo 75) + +inputEx :: [Int] +inputEx = [125, 17] + +main :: IO () +main = do + Right input <- parseOnly parseInput <$> T.readFile "inputs/day11.input" + putStrLn "Part 1" + print $ solveA $ V.fromList inputEx + print $ solveA $ V.fromList input + print $ solveA' input + putStrLn "Part 2" + print $ solveB input