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..024fcd2 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 + - chimera 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..1f3ee88 --- /dev/null +++ b/src/Day11.hs @@ -0,0 +1,64 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Day11 where + +import Control.Parallel.Strategies +import Data.Attoparsec.Text (Parser, decimal, parseOnly, sepBy) +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 = V.singleton 1 +applyRule n + | even len && n > 10 = + V.fromList [n `div` 10 ^ half, n `mod` 10 ^ half] + where + half :: Int + half = len `div` 2 + len :: Int + len = ceiling (logBase 10 (fromIntegral n) :: Float) +applyRule n = V.singleton $ n * 2024 + +-- whnfElements :: (V.Unbox a) => Vector a -> Vector a +-- whnfElements v = V.foldl' (flip seq) () v `seq` v + +solveA :: Vector Int -> Int +solveA = V.length . miterThis 25 + +miterThis :: Int -> Vector Int -> Vector Int +miterThis i v = map (`iterThis` v) [0 ..] !! i + where + iterThis :: Int -> Vector Int -> Vector Int + iterThis 0 vx = vx + iterThis n vx = + traceShowWith V.length $ + miterThis (n - 1) (V.concatMap applyRule vx) + +solveB :: Vector Int -> Int +solveB = V.length . miterThis 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 + putStrLn "Part 2" + print $ solveB $ V.fromList input