diff options
Diffstat (limited to '')
-rw-r--r-- | 2020/03-Toboggan_Trajectory/first.hs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/2020/03-Toboggan_Trajectory/first.hs b/2020/03-Toboggan_Trajectory/first.hs new file mode 100644 index 0000000..55b06b1 --- /dev/null +++ b/2020/03-Toboggan_Trajectory/first.hs @@ -0,0 +1,50 @@ +-- requires cabal install --lib megaparsec +module Main (main) where + +import Control.Monad (void, when) +import Data.List (foldl') +import Data.Void +import Text.Megaparsec +import Text.Megaparsec.Char +import System.Exit (die) + +exampleExpectedOutput = 7 + +type Line = [Bool] +type Field = [Line] + +type Parser = Parsec Void String + +parseElt :: Parser Bool +parseElt = do + c <- (char '#') <|> (char '.') + return $ c == '#' + +parseLine :: Parser Line +parseLine = some parseElt <* char '\n' + +parseField :: Parser Field +parseField = some parseLine <* eof + +parseInput :: String -> IO Field +parseInput filename = do + input <- readFile filename + case runParser parseField filename input of + Left bundle -> die $ errorBundlePretty bundle + Right field -> return field + +compute :: Field -> Int +compute field = snd $ foldl' tree (0, 0) field + where + tree :: (Int, Int) -> Line -> (Int, Int) + tree (index, trees) l = (next index, trees + if l !! index then 1 else 0) + next n = (n + 3) `mod` fieldLen + fieldLen = length $ field !! 0 + +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 |