[hs] Solve 2019_06
This commit is contained in:
parent
f0faf2f591
commit
589eced514
3 changed files with 67 additions and 0 deletions
|
|
@ -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'
|
||||||
|
|
|
||||||
|
|
@ -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
61
hs/src/Aoc/Y2019/D06.hs
Normal 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue