59 lines
2 KiB
Haskell
59 lines
2 KiB
Haskell
data Position = Pos {x::Int, y::Int}
|
|
data PositionRotated = PosR {xR::Int, yR::Int}
|
|
|
|
instance Show Position where
|
|
show (Pos x y) = show (x,y)
|
|
|
|
instance Show PositionRotated where
|
|
show (PosR x y) = show (x,y) ++ "'"
|
|
|
|
|
|
data Sensor = Sensor { position :: Position, beacon::Position } deriving Show
|
|
data SensorRotated = SensorRotated { positionR :: PositionRotated, beaconR :: PositionRotated } deriving Show
|
|
|
|
maxX (Sensor (Pos x _) (Pos x' _)) = maximum [x,x']
|
|
maxY (Sensor (Pos _ y) (Pos _ y')) = maximum [y,y']
|
|
|
|
class RotatePair a b where
|
|
rotateS :: Int -> a -> b
|
|
|
|
instance RotatePair Sensor SensorRotated where
|
|
rotateS = rotateSensor
|
|
|
|
instance RotatePair SensorRotated Sensor where
|
|
rotateS = rotateSensor'
|
|
|
|
rotate :: Int -> Position -> PositionRotated
|
|
rotate width (Pos x y) = PosR (x+y) (width - x + y)
|
|
|
|
rotate' :: Int -> PositionRotated -> Position
|
|
rotate' width (PosR a b) = let y = ((b+a-width) `div` 2) in Pos (a-y) y
|
|
|
|
-- parseLine :: String -> Sensor
|
|
parseLine l = Sensor (Pos (read sx) (read sy)) (Pos (read bx) (read by))
|
|
where (sx,(_:_:_:_:ys)) = span(/=',') (drop (length "Sensor at x=") l)
|
|
(sy,beaconLine) = span(/=':') ys
|
|
(bx,(_:_:_:_:by)) = span(/=',') (drop (length ": closest beacon is at x=") beaconLine)
|
|
|
|
parseInput = map parseLine.lines
|
|
|
|
short = readFile "day15short" >>= pure.parseInput
|
|
|
|
rotateSensor :: Int -> Sensor -> SensorRotated
|
|
rotateSensor width (Sensor p b) = SensorRotated (rotate width p) (rotate width b)
|
|
|
|
rotateSensor' :: Int -> SensorRotated -> Sensor
|
|
rotateSensor' width (SensorRotated p b) = Sensor (rotate' width p) (rotate' width b)
|
|
|
|
oneBeacon :: SensorRotated -> ((Int,Int),(Int, Int))
|
|
oneBeacon (SensorRotated (PosR x y) (PosR bx by)) = ((x-distance, y-distance),(x+distance, y+distance))
|
|
where distance = max (abs (x-bx)) (abs (y-by))
|
|
|
|
puzzle1 = do
|
|
input <- short
|
|
let (height, width) = (maximum $ map maxX input,maximum $ map maxY input)
|
|
print (width, height)
|
|
let rotatedSensors = map (rotateS width) input
|
|
-- let relevantSensors = filter (relevant 10) rotatedSensors
|
|
print rotatedSensors
|
|
|