39 lines
1.1 KiB
Haskell
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 |