Optimised day 19
[advent-of-code-22.git] / advent22 / Main.hs
index 93af26916a4a5e139f484816c96ddd061a4fdae1..848be83e062923f8148bd79046cfc307411d884f 100644 (file)
@@ -1,6 +1,7 @@
 -- Writeup at https://work.njae.me.uk/2022/12/19/advent-of-code-2022-day-18/
 
-import Debug.Trace
+-- import Debug.Trace
+
 
 import AoC
 import Prelude hiding (Left, Right)
@@ -10,7 +11,6 @@ import Linear hiding (E)
 import Control.Lens
 import Data.Ix
 import Data.Maybe
-import Data.List
 import Data.Char
 import Control.Monad.Reader
 
@@ -44,7 +44,10 @@ data Person = Person {_position :: Position, _facing :: Direction}
   deriving (Show, Eq)
 makeLenses ''Person
 
-data Field = Field { getMap :: FieldMap, whatsAheadFunc :: Person -> FieldContext Person, whatsAtFunc :: Position -> FieldContext Cell}
+data Field = Field { getMap :: FieldMap
+                   , whatsAheadFunc :: Person -> FieldContext Person
+                   -- , whatsAtFunc :: Position -> FieldContext Cell
+                   }
 type FieldContext = Reader Field
 
 data Face = A | B | C | D | E | F
@@ -59,6 +62,7 @@ main =
       print $ part2 field instrs
       -- print $ probeAllCorners field
 
+part1, part2 :: FieldMap -> [PathElement] -> Int
 part1 fieldMap instrs = passwordOf endPerson
   where field = mkFlatField fieldMap
         startPos = V2 0 $ fromJust $ minimumOf (folded . filteredBy (_r . only 0) . _c) $ M.keysSet fieldMap
@@ -100,14 +104,16 @@ mkFlatField :: FieldMap -> Field
 mkFlatField fieldMap = 
   Field { getMap = fieldMap
         , whatsAheadFunc = whatsAheadFlat
-        , whatsAtFunc = whatsAt}
+        -- , whatsAtFunc = whatsAt
+        }
 
 
 mkCubeField :: FieldMap -> Field
 mkCubeField fieldMap = 
   Field { getMap = fieldMap
         , whatsAheadFunc = whatsAheadCube
-        , whatsAtFunc = whatsAt}
+        -- , whatsAtFunc = whatsAt
+        }
 
 whatsAt :: Position -> FieldContext Cell
 whatsAt posiiton =
@@ -194,8 +200,6 @@ crossEdge person face =
     (Down,  F) -> person & position . _r .~ 0 & position . _c .~ (interpol c 100 149)
     (Left,  F) -> person & position . _r .~ 0 & position . _c .~ (interpol r 50 99) & facing .~ Down
 
-    otherwise -> error ("Crossing illegal boundary "  ++ show (person, face))
-
   where r = person ^. position . _r
         c = person ^. position . _c
         d = person ^. facing
@@ -203,10 +207,7 @@ crossEdge person face =
 
 
 walk :: Person -> [PathElement] -> FieldContext Person
-walk person [] = return person
-walk person (step:steps) = 
-  do person' <- walkOne person step
-     walk person' steps
+walk person path = foldM walkOne person path
 
 walkOne :: Person -> PathElement -> FieldContext Person
 walkOne person (Forward n) 
@@ -214,7 +215,7 @@ walkOne person (Forward n)
   | otherwise = 
       do whatsAhead <- asks whatsAheadFunc
          person' <- whatsAhead person
-         whatsAt <- asks whatsAtFunc
+         -- whatsAt <- asks whatsAtFunc
          nextCell <- whatsAt (person' ^. position)
          if nextCell == Wall 
          then return person
@@ -248,17 +249,21 @@ mkField rows = M.fromList
           | cell == '#' = Wall
           where cell = (rows !! r) !! c
 
+isCell :: Int -> Int -> [String] -> Bool
 isCell r c rows = isRow && isCol && ((rows !! r) !! c) `elem` (".#" :: String)
   where isRow = r < length rows
         isCol = c < (length $ rows !! r)
 
-mkInstructions :: String -> [PathElement]
+mkInstructions, mkWalk, mkTurn :: String -> [PathElement]
 mkInstructions [] = []
-mkInstructions text@(t:ts)
+mkInstructions text@(t:_)
   | isDigit t = mkWalk text
   | otherwise = mkTurn text
+
 mkWalk text = (Forward $ read digits) : (mkInstructions remainder)
   where (digits, remainder) = span (isDigit) text
+
+mkTurn [] = []
 mkTurn (t:ts) 
   | t == 'R' = Clockwise : (mkInstructions ts)
   | t == 'L' = Anticlockwise : (mkInstructions ts)