[hs] Solve 2019_03

This commit is contained in:
Joscha 2020-11-03 22:24:01 +00:00
parent 0a99b9b647
commit 4044d6aabf
2 changed files with 82 additions and 0 deletions

80
hs/src/Aoc/Y2019/A03.hs Normal file
View file

@ -0,0 +1,80 @@
{-# LANGUAGE OverloadedStrings #-}
module Aoc.Y2019.A03
( solve201903
) where
import Data.List
import Data.Maybe
import qualified Data.Map.Strict as M
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Text.Read (readMaybe)
data Pos = Pos Int Int
deriving (Show, Eq, Ord)
zeroPos :: Pos
zeroPos = Pos 0 0
addPos :: Pos -> Pos -> Pos
addPos (Pos x1 y1) (Pos x2 y2) = Pos (x1 + x2) (y1 + y2)
manhattan :: Pos -> Int
manhattan (Pos x y) = abs x + abs y
data Dir = U | D | L | R
deriving (Show)
asDelta :: Dir -> Pos
asDelta U = Pos 0 1
asDelta D = Pos 0 (-1)
asDelta L = Pos (-1) 0
asDelta R = Pos 1 0
data Step = Step Dir Int
deriving (Show)
step :: Step -> Pos -> [Pos]
step (Step dir n) = take n . drop 1 . iterate (addPos delta)
where delta = asDelta dir
steps :: Pos -> [Step] -> [Pos]
steps pos = concat . drop 1 . scanl' (flip step . last) [pos]
costs :: [Pos] -> M.Map Pos Int
costs = M.fromList . reverse . flip zip [1..]
intersections :: [Step] -> [Step] -> [(Pos, Int)]
intersections s1 s2 =
let costs1 = costs $ steps zeroPos s1
costs2 = costs $ steps zeroPos s2
in M.toList $ M.intersectionWith (+) costs1 costs2
-- Reading input
readDir :: Char -> Maybe Dir
readDir 'U' = Just U
readDir 'D' = Just D
readDir 'L' = Just L
readDir 'R' = Just R
readDir _ = Nothing
readStep :: String -> Maybe Step
readStep [] = Nothing
readStep (d:n) = Step <$> readDir d <*> readMaybe n
readSteps :: T.Text -> Maybe [Step]
readSteps = traverse (readStep . T.unpack) . T.splitOn ","
solve201903 :: FilePath -> IO ()
solve201903 f = do
text <- T.readFile f
let [steps1, steps2] = mapMaybe readSteps $ T.lines text
ixs = intersections steps1 steps2
putStrLn ">> Part 1"
print $ manhattan $ fst $ head $ sortOn (manhattan . fst) ixs
putStrLn ">> Part 2"
print $ snd $ head $ sortOn snd ixs