X-Git-Url: https://git.njae.me.uk/?p=advent-of-code-18.git;a=blobdiff_plain;f=src%2Fadvent25%2Fadvent25.hs;fp=src%2Fadvent25%2Fadvent25.hs;h=5cbd71fe57f97f084913959481c8230d680f767c;hp=0000000000000000000000000000000000000000;hb=1c89812975f9bc5f12e92625d35fe390f5486535;hpb=548c9bd095213b388debfb09ba9727b2174b21d4 diff --git a/src/advent25/advent25.hs b/src/advent25/advent25.hs new file mode 100644 index 0000000..5cbd71f --- /dev/null +++ b/src/advent25/advent25.hs @@ -0,0 +1,104 @@ +{-# LANGUAGE NegativeLiterals #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeFamilies #-} + +import Debug.Trace + +-- import Prelude hiding ((++)) +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as TIO + +import Data.Void (Void) +import Text.Megaparsec hiding (State) +import Text.Megaparsec.Char +import qualified Text.Megaparsec.Char.Lexer as L +import qualified Control.Applicative as CA + +import Data.List hiding (group) +-- import Data.Function (on) +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) + +import Linear (V4(..), (^-^)) + + +type Coord = V4 Integer +type Constellations = M.Map Coord Coord + + +main :: IO () +main = do + text <- TIO.readFile "data/advent25.txt" + let stars = successfulParse text + print $ part1 stars + + +part1 :: [Coord] -> Int +part1 stars = countConstellations constellations + where initialConstellations = foldl' (\c s -> M.insert s s c) M.empty stars + pairs = adjacencies stars + constellations = findConstellations initialConstellations pairs + + +manhattan :: Coord -> Integer +manhattan (V4 x y z t) = (abs x) + (abs y) + (abs z) + (abs t) + +distance :: Coord -> Coord -> Integer +distance a b = manhattan (a ^-^ b) + +close :: Coord -> Coord -> Bool +close a b = (distance a b) <= 3 + +adjacencies :: [Coord] -> [(Coord, Coord)] +adjacencies stars = filter (\(a, b) -> a /= b && (close a b)) + [ (a, b) | a <- stars, b <- stars ] + + +findConstellations :: Constellations -> [(Coord, Coord)] -> Constellations +findConstellations constellations0 pairs = foldl' mergeConstellation constellations0 pairs + +mergeConstellation :: Constellations -> (Coord, Coord) -> Constellations +mergeConstellation constellations (a, b) = + if ae == be + then constellations + else M.insert ae be constellations + where ae = exemplar constellations a + be = exemplar constellations b + +exemplar :: Constellations -> Coord -> Coord +exemplar constellations star = + if constellations!star == star + then star + else exemplar constellations (constellations!star) + + +countConstellations :: Constellations -> Int +countConstellations constellations = M.size $ M.filterWithKey (==) constellations + + +type Parser = Parsec Void Text + +sc :: Parser () +sc = L.space (skipSome spaceChar) CA.empty CA.empty + +lexeme = L.lexeme sc +integer = lexeme L.decimal +signedInteger = L.signed sc integer +symb = L.symbol sc +comma = symb "," + +coordP = V4 <$> signedInteger <* comma + <*> signedInteger <* comma + <*> signedInteger <* comma + <*> signedInteger + +starsP = many coordP + +successfulParse :: Text -> [Coord] +-- successfulParse _ = [] +successfulParse input = + case parse starsP "input" input of + Left _error -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err + Right stars -> stars