diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2021-12-13 11:02:06 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2021-12-13 12:05:34 +0200 |
| commit | 197f07c4ad5c71b821a5dcdc84d01eec07ff64f6 (patch) | |
| tree | 32192f602dc00614a2000adb84c7196d539a8b7c /day13/main.hs | |
| parent | 96feb113538b18d615b02fc5886dd66abfd79d19 (diff) | |
Day 13
Diffstat (limited to 'day13/main.hs')
| -rw-r--r-- | day13/main.hs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/day13/main.hs b/day13/main.hs new file mode 100644 index 0000000..fd81216 --- /dev/null +++ b/day13/main.hs @@ -0,0 +1,68 @@ +{-# LANGUAGE LambdaCase #-} + +module Main where + +import Data.Bifunctor (bimap, first, second) +import Data.List (foldl', nub) +import Data.Set (Set) +import qualified Data.Set as Set +import Data.Text (isPrefixOf, pack, split, unpack) +import Utils + +type Point = (Int, Int) + +data Fold = LeftFold Int | UpFold Int deriving (Show) + +parseFold :: String -> Fold +parseFold s = + let (coord, num) = drop 11 s $> splitToPair (== '=') + in if coord == "x" + then LeftFold (read num) + else UpFold (read num) + +foldLeft :: Int -> [Point] -> [Point] +foldLeft yLine = map (first (\x -> min x $ yLine + (yLine - x))) .> nub + +foldUp :: Int -> [Point] -> [Point] +foldUp xLine = map (second (\y -> min y $ xLine + (xLine - y))) .> nub + +doFold points fold = case fold of + LeftFold yLine -> foldLeft yLine points + UpFold xLine -> foldUp xLine points + +e1 :: [Point] -> [Fold] -> [Point] +e1 points folds = + doFold points (head folds) + +printCode :: [Point] -> IO () +printCode points = + let pointsSet = Set.fromList points + xSize = maximum (map fst points) + 1 + ySize = maximum (map snd points) + 1 + pointToChar p = if p `elem` pointsSet then '#' else '.' + rowStrs = [0 .. ySize - 1] $> map (\y -> [0 .. xSize - 1] $> map (\x -> pointToChar (x, y))) + in rowStrs $> map putStrLn .> sequence_ + +e2 = + foldl' doFold + +main :: IO () +main = + do + contents <- getContents + + let input = + contents + $> lines + .> break null + let pointsStr = fst input + let foldsStr = snd input $> drop 1 + + let points = pointsStr $> map (splitToPair (== ',') .> bimap read read) :: [Point] + let folds = foldsStr $> map parseFold + + let result1 = e1 points folds + result1 $> length .> print + let result2 = e2 points folds + result2 $> length .> print + result2 $> printCode |
