aoc2021/Day5.hs

49 lines
1.5 KiB
Haskell

module Day5 where
import System.IO (openFile, IOMode (ReadMode), hClose, hGetContents)
import Data.Text (splitOn, unpack, pack)
import Prelude hiding (splitAt)
import Data.List (sort, intersect)
type Coordinate = (Int, Int)
type Range = ([Int], [Int])
toCoord :: String -> Coordinate
toCoord str = (x, y)
where
xy = splitAt "," str
x = read $ head xy
y = read $ xy !! 1
isStraight :: Coordinate -> Coordinate -> Bool
isStraight c1 c2 = fst c1 == fst c2 || snd c1 == snd c2
splitAt :: String -> String -> [String]
splitAt delimiter str = map unpack $ splitOn (pack delimiter) $ pack str
coordsToRange :: (Coordinate, Coordinate) -> Range
coordsToRange (a, b) = ([fst a..fst b], [snd a.. snd b])
points :: Range -> [Coordinate]
points range = [ (i,j) | i <- fst range, j <- snd range ]
intersections :: [Range] -> [[Coordinate]]
intersections [] = []
intersections (x:xs) = map (\y -> points x `intersect` points y) xs ++ intersections xs
dedup :: Eq a => [(a, a)] -> [(a, a)]
dedup [] = []
dedup (x:xs) = x : dedup (filter (x /=) xs)
main :: IO ()
main = do
input <- openFile "inputs/5.txt" ReadMode
contents <- hGetContents input
let coords = map toCoord . splitAt " -> " <$> lines contents
-- remove lines that aren't horizontal/vertical and sort them
let lines = map sort $ filter (\x -> isStraight (head x) (x !! 1)) coords
let pairs = map (coordsToRange . (\x -> (head x, x !! 1))) lines
print . length . dedup . concat $ intersections pairs
hClose input