1- {-# OPTIONS_GHC -Wno-unused-imports #-}
2- {-# OPTIONS_GHC -Wno-unused-top-binds #-}
3-
41-- |
52-- Module : AOC2025.Day07
63-- License : BSD3
96-- Portability : non-portable
107--
118-- Day 7. See "AOC.Solver" for the types used in this module!
12- --
13- -- After completing the challenge, it is recommended to:
14- --
15- -- * Replace "AOC.Prelude" imports to specific modules (with explicit
16- -- imports) for readability.
17- -- * Remove the @-Wno-unused-imports@ and @-Wno-unused-top-binds@
18- -- pragmas.
19- -- * Replace the partial type signatures underscores in the solution
20- -- types @_ :~> _@ with the actual types of inputs and outputs of the
21- -- solution. You can delete the type signatures completely and GHC
22- -- will recommend what should go in place of the underscores.
239module AOC2025.Day07 (
2410 day07a ,
2511 day07b ,
2612)
2713where
2814
29- import AOC.Prelude
30- import qualified Data.Graph.Inductive as G
31- import qualified Data.IntMap as IM
32- import qualified Data.IntMap.NonEmpty as NEIM
33- import qualified Data.IntSet as IS
34- import qualified Data.IntSet.NonEmpty as NEIS
35- import qualified Data.List.NonEmpty as NE
36- import qualified Data.List.PointedList as PL
37- import qualified Data.List.PointedList.Circular as PLC
15+ import AOC.Common (countTrue , firstJust )
16+ import AOC.Common.Point (Point , parseAsciiMap )
17+ import AOC.Solver (noFail , (:~>) (.. ))
18+ import Control.Lens (view )
19+ import Data.Foldable (toList )
3820import qualified Data.Map as M
21+ import Data.Map.NonEmpty (NEMap )
3922import qualified Data.Map.NonEmpty as NEM
40- import qualified Data.OrdPSQ as PSQ
41- import qualified Data.Sequence as Seq
42- import qualified Data.Sequence.NonEmpty as NESeq
43- import qualified Data.Set as S
23+ import Data.Maybe (fromMaybe )
24+ import Data.Set.NonEmpty (NESet )
4425import qualified Data.Set.NonEmpty as NES
45- import qualified Data.Text as T
46- import qualified Data.Vector as V
47- import qualified Linear as L
48- import qualified Text.Megaparsec as P
49- import qualified Text.Megaparsec.Char as P
50- import qualified Text.Megaparsec.Char.Lexer as PP
26+ import Linear.V2 (V2 (.. ), _y )
5127
5228parseMap :: String -> Maybe (Point , NESet Point )
5329parseMap =
@@ -57,7 +33,7 @@ parseMap =
5733 where
5834 reshape (startPos, rest) = (,) . fst <$> M. lookupMin startPos <*> NES. nonEmptySet (M. keysSet rest)
5935
60- day07a :: _ :~> _
36+ day07a :: ( Point , NESet Point ) :~> Int
6137day07a =
6238 MkSol
6339 { sParse = parseMap
@@ -66,22 +42,22 @@ day07a =
6642 noFail $ \ (startPos, splitters) ->
6743 let pathsTo :: NEMap Point Bool
6844 pathsTo = flip NEM. fromSet splitters \ (V2 x y0) ->
69- let cands = takeWhile ((`NES.notMember` splitters) . V2 x) [y0 - 1 , y0 - 2 .. 0 ]
45+ let cands = takeWhile ((`NES.notMember` splitters) . V2 x) [y0 - 2 , y0 - 4 .. 0 ]
7046 in flip any cands \ y ->
7147 V2 x y == startPos
7248 || NEM. findWithDefault False (V2 (x - 1 ) y) pathsTo
7349 || NEM. findWithDefault False (V2 (x + 1 ) y) pathsTo
7450 in countTrue id pathsTo
7551 }
7652
77- day07b :: _ :~> _
53+ day07b :: ( Point , NESet Point ) :~> Int
7854day07b =
7955 MkSol
8056 { sParse = parseMap
8157 , sShow = show
8258 , sSolve = \ (startPos, splitters) -> do
83- let maxY = maximum $ NES. map (view _y) splitters
84- downFrom (V2 x y0) = fromMaybe 1 $ flip firstJust [y0 .. maxY] \ y ->
59+ let maxY = maximum . map (view _y) $ toList splitters
60+ downFrom (V2 x y0) = fromMaybe 1 $ flip firstJust [y0, y0 + 2 .. maxY] \ y ->
8561 NEM. lookup (V2 x y) pathsFrom
8662 pathsFrom :: NEMap Point Int
8763 pathsFrom = flip NEM. fromSet splitters \ p ->
0 commit comments