adventofcode/2022/day15.hs

39 lines
1.1 KiB
Haskell

import Data.List.Split (splitOn)
import qualified Data.Set as S
type Coord = (Int, Int)
globalY :: Int
globalY = 2000000
parseCoord :: String -> Coord
parseCoord xs = (read $ init x, read y) where
[x,y] = map (drop 2) $ splitOn " " xs
parseLine :: String -> (Coord, Coord)
parseLine xs = (sensor, beacon) where
[sensor, beacon] = map (parseCoord . dropWhile (/='x'))$ splitOn ":" xs
manhattan :: Coord -> Coord -> Int
manhattan (a,b) (x,y) = abs (a-x) + abs (b-y)
allWithinRange :: Coord -> Coord -> S.Set Coord
allWithinRange sensor@(a,b) beacon@(x,y) = S.fromList $ filter (\c -> manhattan sensor c <= dist) all where
minx = a - dist
maxx = a + dist
miny = b - dist
maxy = b + dist
dist = manhattan sensor beacon
all = [(x,y) | x <- [minx..maxx], y <- [globalY]]
main :: IO ()
main = do
x <- map parseLine . lines <$> getContents
let beacons = S.fromList $ map snd x
let reachable = foldr1 S.union $ map (uncurry allWithinRange) x
let ys = S.size $ S.filter (\x -> snd x == globalY) (reachable S.\\ beacons)
putStr "part 1: "
print ys