[hs] Solve 2019_06

This commit is contained in:
Joscha 2020-12-06 22:25:03 +00:00
parent f0faf2f591
commit 589eced514
3 changed files with 67 additions and 0 deletions

View file

@ -8,6 +8,7 @@ module Aoc.Parse
, untilSpace , untilSpace
, untilEol , untilEol
, lineChar , lineChar
, word
, digit , digit
) where ) where
@ -41,6 +42,9 @@ untilEol = takeWhileP (Just "non-newline character") (/= '\n')
lineChar :: Parser Char lineChar :: Parser Char
lineChar = label "non-newline character" $ satisfy (/= '\n') lineChar = label "non-newline character" $ satisfy (/= '\n')
word :: Parser T.Text
word = takeWhileP (Just "alphanumeric character") isAlphaNum
digit :: Num a => Parser a digit :: Num a => Parser a
digit = foldr1 (<|>) digit = foldr1 (<|>)
[ 0 <$ char '0' [ 0 <$ char '0'

View file

@ -8,6 +8,7 @@ import qualified Aoc.Y2019.D02 as D02
import qualified Aoc.Y2019.D03 as D03 import qualified Aoc.Y2019.D03 as D03
import qualified Aoc.Y2019.D04 as D04 import qualified Aoc.Y2019.D04 as D04
import qualified Aoc.Y2019.D05 as D05 import qualified Aoc.Y2019.D05 as D05
import qualified Aoc.Y2019.D06 as D06
year :: Year year :: Year
year = Year 2019 year = Year 2019
@ -16,4 +17,5 @@ year = Year 2019
, ( 3, D03.day) , ( 3, D03.day)
, ( 4, D04.day) , ( 4, D04.day)
, ( 5, D05.day) , ( 5, D05.day)
, ( 6, D06.day)
] ]

61
hs/src/Aoc/Y2019/D06.hs Normal file
View file

@ -0,0 +1,61 @@
{-# LANGUAGE OverloadedStrings #-}
module Aoc.Y2019.D06
( day
) where
import Data.Maybe
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Text as T
import Aoc.Day
import Aoc.Parse
data Tree = Tree T.Text [Tree]
deriving (Show)
buildTree :: Map.Map T.Text [T.Text] -> T.Text -> Tree
buildTree m e = Tree e $ map (buildTree m) $ Map.findWithDefault [] e m
orbits :: Tree -> Int
orbits = helper 0
where
helper depth (Tree _ ts) = (depth +) $ sum $ map (helper $ depth + 1) ts
pathTo :: T.Text -> Tree -> Maybe [T.Text]
pathTo target (Tree name ts)
| name == target = Just [name]
| otherwise = case mapMaybe (pathTo target) ts of
(x:_) -> Just $ name : x
[] -> Nothing
differentParts :: (Eq a) => [a] -> [a] -> ([a], [a])
differentParts (a:as) (b:bs) | a == b = differentParts as bs
differentParts as bs = (as, bs)
parser :: Parser [(T.Text, T.Text)]
parser = manyLines $ (,) <$> (word <* char ')') <*> word
solver :: [(T.Text, T.Text)] -> IO ()
solver pairs = do
let orbitMap = Map.fromListWith (++) $ map (\(a, b) -> (a, [b])) pairs
roots = Set.fromList (map fst pairs) Set.\\ Set.fromList (concat $ Map.elems orbitMap)
[tree] = map (buildTree orbitMap) $ Set.toList roots
putStrLn ">> Part 1"
print $ orbits tree
putStrLn ""
putStrLn ">> Part 2"
let l = do
p1 <- pathTo "YOU" tree
p2 <- pathTo "SAN" tree
let (p1', p2') = differentParts p1 p2
-- Between orbiting bodies, not SAN and YOU themselves, hence the -2
pure $ length p1' + length p2' - 2
print l
day :: Day
day = dayParse parser solver