aboutsummaryrefslogtreecommitdiff
path: root/2021/day13/13b.hs
blob: 32d29de953de32be2b9b2131e65ee5df25a53193 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where

import qualified Data.Text as T
import Data.Set (Set)
import Data.List
import qualified Data.Set as S

type Coord = (Int, Int)
data FoldInstr = Fold Axis Int deriving (Show, Eq, Ord)
data Axis = XAxis | YAxis deriving (Show, Eq, Ord)

parseCoords :: String -> Coord
parseCoords s = (read x, read y)
  where [x, y] = map T.unpack $ T.splitOn "," (T.pack s)

parseFold :: String -> FoldInstr
parseFold (stripPrefix "fold along y=" -> Just cs) = Fold YAxis (read cs)
parseFold (stripPrefix "fold along x=" -> Just cs) = Fold XAxis (read cs)

parseFile :: String -> (Set Coord, [FoldInstr])
parseFile s = (S.fromList $ map parseCoords (lines coordSection), map parseFold (lines foldSection))
  where [coordSection, foldSection] = map T.unpack $ T.splitOn "\n\n" (T.pack s)

performFold :: Set Coord -> FoldInstr -> Set Coord
performFold coords (Fold YAxis ye) = S.map (\(x, y) -> (x, -(abs (y - ye)) + ye)) coords
performFold coords (Fold XAxis xe) = S.map (\(x, y) -> (-(abs (x - xe)) + xe, y)) coords

displayCoords :: Set Coord -> String
displayCoords coords = intercalate "\n" (map displayLine [sy..ey])
  where sx = minimum (S.map fst coords)
        ex = maximum (S.map fst coords)
        sy = minimum (S.map snd coords)
        ey = maximum (S.map snd coords)
        displayLine y = map (displayCoord y) [sx..ex]
        displayCoord y x | S.member (x, y) coords = '#'
                         | otherwise              = '.'

main :: IO ()
main = do
  f <- readFile "./input"
  let (coords, instrs) = parseFile f;
  let result = foldl performFold coords instrs;
  putStrLn $ displayCoords result