part2 grid guard = length $ filter (isLoop guard []) modifiedGrids
where modifiedGrids = [ grid // [ (new, True) ]
- | new <- news -- range (bounds grid)
+ | new <- news
, new /= guard.pos
]
news = nub $ walk grid guard
| otherwise = Just (guard.pos, guard { pos = ahead })
where ahead = guard.pos ^+^ guard.dir
--- isLoop :: Guard -> [Guard] -> Grid -> Bool
--- isLoop guard trail grid
--- | isNothing stepped = False
--- | guard' `elem` trail = True
--- | otherwise = isLoop guard' (guard:trail) grid
--- where stepped = step grid guard
--- (_, guard') = fromJust stepped
+
isLoop :: Guard -> [Guard] -> Grid -> Bool
isLoop guard trail grid
| isNothing stepped = False
part2 grid guard = length $ filter id loopResults
where modifiedGrids = [ grid // [ (new, True) ]
- | new <- news -- range (bounds grid)
+ | new <- news
, new /= guard.pos
]
loopResults = parMap rpar (isLoop guard []) modifiedGrids
| otherwise = Just (guard.pos, guard { pos = ahead })
where ahead = guard.pos ^+^ guard.dir
--- isLoop :: Guard -> [Guard] -> Grid -> Bool
--- isLoop guard trail grid
--- | isNothing stepped = False
--- | guard' `elem` trail = True
--- | otherwise = isLoop guard' (guard:trail) grid
--- where stepped = step grid guard
--- (_, guard') = fromJust stepped
isLoop :: Guard -> [Guard] -> Grid -> Bool
isLoop guard trail grid
| isNothing stepped = False
--- /dev/null
+-- Writeup at https://work.njae.me.uk/2024/12/07/advent-of-code-2024-day-7/
+
+import AoC
+import Data.Text (Text)
+import qualified Data.Text.IO as TIO
+import Data.Attoparsec.Text
+-- import Control.Applicative
+import Data.List
+
+type Calibration = (Int, [Int])
+
+main :: IO ()
+main =
+ do dataFileName <- getDataFileName
+ text <- TIO.readFile dataFileName
+ let calibrations = successfulParse text
+ -- print calibrations
+ print $ part1 calibrations
+ print $ part2 calibrations
+
+part1, part2 :: [Calibration] -> Int
+part1 = sum . (fmap fst) . filter isValid
+part2 = sum . (fmap fst) . filter isValidC
+
+isValid, isValidC :: Calibration -> Bool
+isValid (target, factors) = target `elem` extend factors
+isValidC (target, factors) = target `elem` extendC factors
+
+extend, extendC :: [Int] -> [Int]
+extend (x:xs) = foldl' extendOne [x] xs
+extendC (x:xs) = foldl' extendOneC [x] xs
+
+extendOne, extendOneC :: [Int] -> Int -> [Int]
+extendOne partials next = concatMap go partials
+ where go p = [p + next, p * next]
+
+extendOneC partials next = concatMap go partials
+ where go p = [ p + next
+ , p * next
+ , read (show p ++ show next)
+ ]
+
+-- parse the input file
+
+calibrationsP :: Parser [Calibration]
+calibrationP :: Parser Calibration
+
+calibrationsP = calibrationP `sepBy` endOfLine
+calibrationP = (,) <$> decimal <* ": " <*> (decimal `sepBy` " ")
+
+successfulParse :: Text -> [Calibration]
+successfulParse input =
+ case parseOnly calibrationsP input of
+ Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
+ Right caliibrations -> caliibrations
+
import: warnings, common-extensions, build-directives, common-modules
main-is: advent06/MainPar.hs
build-depends: array, linear, parallel
+
+executable advent07
+ import: warnings, common-extensions, build-directives, common-modules
+ main-is: advent07/Main.hs
+ build-depends: attoparsec, text
+
\ No newline at end of file