|
| 1 | +module Main where |
| 2 | + |
| 3 | +import Control.Parallel.Strategies |
| 4 | +import Data.List.Split |
| 5 | +import Debug.Trace |
| 6 | +import System.Environment |
| 7 | + |
| 8 | +-- TODO: Cleanup imports after day done |
| 9 | + |
| 10 | +type Input = [Int] |
| 11 | + |
| 12 | +type Output = Int |
| 13 | + |
| 14 | +parseInput :: String -> Input |
| 15 | +parseInput = map read . splitOn " " . head . lines |
| 16 | + |
| 17 | +digitCount :: Int -> Int |
| 18 | +digitCount 0 = 1 |
| 19 | +digitCount n = countThem n |
| 20 | + where |
| 21 | + countThem i |
| 22 | + | i < 10 = 1 |
| 23 | + | otherwise = 1 + countThem (div i 10) |
| 24 | + |
| 25 | +splitNumber :: Int -> Int -> [Int] |
| 26 | +splitNumber n lengthn = [firstHalf, secondHalf] |
| 27 | + where |
| 28 | + -- lengthn = digitCount n |
| 29 | + powered10 = {-# SCC powered10 #-} (10 ^ (div lengthn 2)) |
| 30 | + firstHalf = {-# SCC firstHalf #-} div n powered10 |
| 31 | + secondHalf = {-# SCC secondHalf #-} n - (firstHalf * powered10) |
| 32 | + |
| 33 | +iterateStones :: [Int] -> [Int] |
| 34 | +iterateStones stones = concat $ map iterateStone stones |
| 35 | + where |
| 36 | + iterateStone 0 = [1] |
| 37 | + iterateStone stone |
| 38 | + | isSplitable = splitNumber stone stoneLength |
| 39 | + | otherwise = [stone * 2024] |
| 40 | + where |
| 41 | + isSplitable = {-# SCC isSplitable #-} (== 0) $ (`mod` 2) stoneLength |
| 42 | + stoneLength = {-# SCC stoneLength #-} digitCount stone |
| 43 | + |
| 44 | +solve :: Int -> Input -> Output |
| 45 | +solve n arr = length . fst . head . drop n $ iterate (\(l, i) -> trace (show (i, length l)) (iterateStones l, i + 1)) (arr, 0) |
| 46 | + |
| 47 | +part1 :: Input -> Output |
| 48 | +part1 = solve 25 |
| 49 | + |
| 50 | +part2 :: Input -> Output |
| 51 | +part2 = solve 35 |
| 52 | + |
| 53 | +main :: IO () |
| 54 | +main = do |
| 55 | + args <- getArgs |
| 56 | + content <- readFile (last args) |
| 57 | + let input = parseInput content |
| 58 | + |
| 59 | + print input |
| 60 | + |
| 61 | + print $ part1 input |
| 62 | + print $ part2 input |
0 commit comments