From 08fe41ccd586005decf77f7a73c47a0d32f52cdb Mon Sep 17 00:00:00 2001 From: Jack Bond-Preston Date: Sun, 12 Dec 2021 02:22:40 +0000 Subject: [PATCH] day 5 Signed-off-by: Jack Bond-Preston --- 5/5.hs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 5/5.hs diff --git a/5/5.hs b/5/5.hs new file mode 100644 index 0000000..937ce0f --- /dev/null +++ b/5/5.hs @@ -0,0 +1,74 @@ +import System.IO + ( hClose, openFile, hGetContents, IOMode(ReadMode) ) +import Text.Parsec +import Text.Parsec.String +import Control.Monad +import Data.List +import Data.Maybe +import Data.Sequence (replicate, Seq, mapWithIndex) + +import Data.Map (Map, (!)) +import qualified Data.Map as Map + +type Coord = (Int, Int) +type LineEnds = (Coord, Coord) + +type Grid = Map Coord Integer + +int :: Parser Int +int = read <$> many1 digit + +eol :: Parser () +eol = void $ char '\n' + +coord :: Parser Coord +coord = do + x <- int + char ',' + y <- int + + return (x, y) + +arrow :: Parser () +arrow = void $ string " -> " + +line :: Parser LineEnds +line = do + from <- coord + arrow + to <- coord + + return (from, to) + +inputParser :: Parser [LineEnds] +inputParser = line `endBy1` eol + +lineToCellList :: LineEnds -> [Coord] +lineToCellList ((x0, y0), (x1, y1)) + | x0 == x1 = [ (x0, y) | y <- [min y0 y1 .. max y0 y1] ] + | y0 == y1 = [ (x, y0) | x <- [min x0 x1 .. max x0 x1] ] + | otherwise = [ (x, y) | x <- [min x0 x1 .. max x0 x1], + y <- [min y0 y1 .. max y0 y1], + abs (x - x0) == abs (y - y0) ] + +type CoordMap = Map Coord Int + +scoreFold :: Coord -> (CoordMap, Int) -> (CoordMap, Int) +scoreFold coord (map, acc) + | Map.member coord map = if + (map ! coord) == 1 then (Map.adjust (+1) coord map, acc + 1) + else (Map.adjust (+1) coord map, acc) + | otherwise = (Map.insert coord 1 map, acc) + +score :: [LineEnds] -> Int +score les = snd (foldr scoreFold (Map.empty, 0) coords) + where + coords = concatMap lineToCellList les + +main = do + handle <- openFile "input.txt" ReadMode + contents <- hGetContents handle + case parse inputParser "" contents of + Left x -> print x + Right x -> print (score x) + hClose handle