From d34301fc153e85aa7d9ce4621ab8eb98ae7471e1 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Thu, 11 May 2023 23:01:51 +0200 Subject: 2020-22 part 1 in haskell --- 2020/22-Crab_Combat/example | 13 ++++++++++ 2020/22-Crab_Combat/first.hs | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2020/22-Crab_Combat/input | 53 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 2020/22-Crab_Combat/example create mode 100644 2020/22-Crab_Combat/first.hs create mode 100644 2020/22-Crab_Combat/input diff --git a/2020/22-Crab_Combat/example b/2020/22-Crab_Combat/example new file mode 100644 index 0000000..391cd24 --- /dev/null +++ b/2020/22-Crab_Combat/example @@ -0,0 +1,13 @@ +Player 1: +9 +2 +6 +3 +1 + +Player 2: +5 +8 +4 +7 +10 diff --git a/2020/22-Crab_Combat/first.hs b/2020/22-Crab_Combat/first.hs new file mode 100644 index 0000000..084e461 --- /dev/null +++ b/2020/22-Crab_Combat/first.hs @@ -0,0 +1,61 @@ +-- requires cabal install --lib megaparsec parser-combinators +module Main (main) where +import Control.Monad (void, when) +import Data.List qualified as L +import Data.Map qualified as M +import Data.Maybe (catMaybes) +import Data.Set qualified as S +import Data.Void (Void) +import Text.Megaparsec +import Text.Megaparsec.Char +import System.Exit (die) + +exampleExpectedOutput = 306 + +type Card = Int +type Deck = [Card] +type Input = (Deck, Deck) + +type Parser = Parsec Void String + +parseCard :: Parser Card +parseCard = do + n <- some digitChar + void $ optional (char '\n') + return $ read n + +parseDeck :: Parser Deck +parseDeck = string "Player " *> digitChar *> string ":\n" *> some parseCard + +parseInput' :: Parser Input +parseInput' = do + p1 <- parseDeck + void $ char '\n' + p2 <- parseDeck + void $ eof + return (p1, p2) + +parseInput :: String -> IO Input +parseInput filename = do + input <- readFile filename + case runParser parseInput' filename input of + Left bundle -> die $ errorBundlePretty bundle + Right input' -> return input' + +computeScore :: Deck -> Int +computeScore d = sum $ zipWith (*) d (reverse $ take (length d) [1..]) + +compute :: Input -> Int +compute ([], d) = computeScore d +compute (d, []) = computeScore d +compute (a:as, b:bs) + | a > b = compute (as ++ [a, b], bs) + | otherwise = compute (as, bs ++ [b, a]) + +main :: IO () +main = do + example <- parseInput "example" + let exampleOutput = compute example + when (exampleOutput /= exampleExpectedOutput) (die $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput) + input <- parseInput "input" + print $ compute input diff --git a/2020/22-Crab_Combat/input b/2020/22-Crab_Combat/input new file mode 100644 index 0000000..cb8d1e5 --- /dev/null +++ b/2020/22-Crab_Combat/input @@ -0,0 +1,53 @@ +Player 1: +48 +23 +9 +34 +37 +36 +40 +26 +49 +7 +12 +20 +6 +45 +14 +42 +18 +31 +39 +47 +44 +15 +43 +10 +35 + +Player 2: +13 +19 +21 +32 +27 +16 +11 +29 +41 +46 +33 +1 +30 +22 +38 +5 +17 +4 +50 +2 +3 +28 +8 +25 +24 -- cgit v1.2.3