Skip to content
This repository has been archived by the owner on Nov 17, 2024. It is now read-only.

Commit

Permalink
day 18 progress
Browse files Browse the repository at this point in the history
  • Loading branch information
mstksg committed Dec 21, 2023
1 parent 4084024 commit 399137d
Showing 1 changed file with 73 additions and 54 deletions.
127 changes: 73 additions & 54 deletions src/AOC/Challenge/Day18.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# OPTIONS_GHC -Wno-unused-top-binds #-}

-- |
Expand All @@ -20,65 +20,90 @@
-- types @_ :~> _@ with the actual types of inputs and outputs of the
-- solution. You can delete the type signatures completely and GHC
-- will recommend what should go in place of the underscores.
module AOC.Challenge.Day18
( day18a,
day18b,
)
where

module AOC.Challenge.Day18 (
day18a
, day18b
) where

import AOC.Prelude

import qualified Data.Graph.Inductive as G
import qualified Data.IntMap as IM
import qualified Data.IntSet as IS
import qualified Data.List.NonEmpty as NE
import qualified Data.List.PointedList as PL
import qualified Data.List.PointedList.Circular as PLC
import qualified Data.Map as M
import qualified Data.OrdPSQ as PSQ
import qualified Data.Sequence as Seq
import qualified Data.Set as S
import qualified Data.Text as T
import qualified Data.Vector as V
import qualified Linear as L
import AOC.Prelude
import Data.Bitraversable
import qualified Text.Megaparsec as P
import qualified Text.Megaparsec.Char as P
import qualified Text.Megaparsec.Char.Lexer as PP
import qualified Data.Graph.Inductive as G
import qualified Data.IntMap as IM
import qualified Data.IntSet as IS
import qualified Data.List.NonEmpty as NE
import qualified Data.List.PointedList as PL
import qualified Data.List.PointedList.Circular as PLC
import qualified Data.Map as M
import qualified Data.OrdPSQ as PSQ
import qualified Data.Sequence as Seq
import qualified Data.Set as S
import qualified Data.Text as T
import qualified Data.Vector as V
import qualified Linear as L
import Numeric.Lens (hex)

-- R 5 (#4f4602)

parseLineA :: String -> Maybe (Dir, Int)
parseLineA = bitraverse (parseDir . head) readMaybe
<=< listTup . take 2 . words
import qualified Text.Megaparsec as P
import qualified Text.Megaparsec.Char as P
import qualified Text.Megaparsec.Char.Lexer as PP

shoelace :: NonEmpty Point -> Int
-- shoelace (z:|zs) = (`div` 2) . abs . sum $ traceShow (zip (z:zs) (zs)) $ zipWith go (z:zs) (zs ++ [z])
shoelace (z:|zs) = (`div` 2) . abs . sum $ zipWith go (z:zs) (zs ++ [z])
shoelace (z :| zs) = (`div` 2) . abs . sum $ zipWith go (z : zs) (zs ++ [z])
where
latterPart = zs ++ [z]
go (V2 x y) (V2 x' y') = x * y' - y * x'

day18a :: _ :~> _
day18a = MkSol
{ sParse = traverse parseLineA . lines
, sShow = show
, sSolve = NE.nonEmpty . flip evalState (0, Nothing) . traverse (uncurry go)
-- , sSolve = fmap shoelace . NE.nonEmpty . scanl' go 0
}
-- | Maps to possible startpoints and possible endpoints
mkSegments :: Bool -> [(Dir, Int)] -> [V2 (Set Point)]
mkSegments clockwise = snd . mapAccumL go 0
where
go :: Dir -> Int -> State (Point, Maybe Dir) [Point]
go d i = state \(p, lastDir) ->
let p' = p + i *^ dirPoint' d
in undefined
-- go p (d, i) = p + i *^ dirPoint' d
go p (d, i) = (p', S.fromList . map (buffer d) . consecs <$> V2 p p')
where
p' = p + i *^ dirPoint' d
consecs q = map (\j -> q + j *^ dirPoint' d) [-1,0,1]
buffer
| clockwise = \case
North -> id
East -> id
South -> (+ V2 1 0)
West -> (+ V2 0 1)
| otherwise = \case
North -> (+ V2 1 0)
East -> (+ V2 1 0)
South -> id
West -> id

-- | Pick the matching points consecutively
joinSegments :: [V2 (Set Point)] -> Maybe [Point]
joinSegments xs = zipWithM go xs (drop 1 xs)
where
go :: V2 (Set Point) -> V2 (Set Point) -> Maybe Point
go (V2 _ a) (V2 b _) = S.lookupMin (a `S.intersection` b)

day18 :: (String -> Maybe (Dir, Int)) -> [(Dir, Int)] :~> Int
day18 p =
MkSol
{ sParse = traverse p . lines,
sShow = show,
sSolve = \xs -> maximumMay
[ shoelace (0 :| border)
| Just border <- joinSegments . (`mkSegments` xs) <$> [False, True]
]
}

parseLineA :: String -> Maybe (Dir, Int)
parseLineA =
bitraverse (parseDir . head) readMaybe
<=< listTup
. take 2
. words

day18a :: [(Dir, Int)] :~> Int
day18a = day18 parseLineA

parseLineB :: String -> Maybe (Dir, Int)
parseLineB = splitUp . filter isHexDigit <=< (!? 2) . words
where
splitUp xs = do
y:ys <- pure $ reverse xs
y : ys <- pure $ reverse xs
d <- case y of
'0' -> pure East
'1' -> pure South
Expand All @@ -88,11 +113,5 @@ parseLineB = splitUp . filter isHexDigit <=< (!? 2) . words
i <- preview (reversed . hex) ys
pure (d, i)

day18b :: _ :~> _
day18b = MkSol
{ sParse = traverse parseLineB . lines
, sShow = show
, sSolve = fmap shoelace . NE.nonEmpty . scanl' go 0
}
where
go p (d, i) = p + i *^ dirPoint d
day18b :: [(Dir, Int)] :~> Int
day18b = day18 parseLineB

0 comments on commit 399137d

Please sign in to comment.