Advent of Code 2021
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
1.5 KiB

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