2019-12-10 21:21:20 +01:00
import Data.List as L
import Data.Maybe
2019-12-11 02:20:24 +01:00
import Data.Ord
import qualified Data.Vector as V
data Asteroid =
Asteroid Int Int
deriving ( Show )
2019-12-10 21:21:20 +01:00
instance Eq Asteroid where
2019-12-14 15:58:16 +01:00
Asteroid a b == Asteroid c d = phi a b == phi c d
2019-12-11 02:20:24 +01:00
2019-12-10 21:21:20 +01:00
instance Ord Asteroid where
2019-12-14 15:56:18 +01:00
Asteroid a b ` compare ` Asteroid c d = phi a b ` compare ` phi c d
2019-12-10 21:21:20 +01:00
2019-12-14 15:58:16 +01:00
phi :: Int -> Int -> Double
phi xi yi
2019-12-14 15:56:18 +01:00
| x >= 0 = atan2 x ( - y )
| otherwise = 2 * pi + atan2 ( - x ) y
where x = fromIntegral xi
y = fromIntegral yi
2019-12-11 02:20:24 +01:00
2019-12-10 21:21:20 +01:00
( -| ) :: Asteroid -> Asteroid -> Asteroid
2019-12-11 02:20:24 +01:00
( -| ) ( Asteroid a b ) ( Asteroid c d ) = Asteroid ( a - c ) ( b - d )
2019-12-10 21:21:20 +01:00
neg :: Asteroid -> Asteroid
neg ( Asteroid a b ) = Asteroid ( - a ) ( - b )
2019-12-11 02:20:24 +01:00
2019-12-10 21:21:20 +01:00
dist :: Asteroid -> Int
dist ( Asteroid x y ) = abs x + abs y
2019-12-14 15:56:18 +01:00
main :: IO ()
2019-12-10 21:21:20 +01:00
main = do
2019-12-11 02:20:24 +01:00
content <- lines <$> readFile " input "
2019-12-14 15:56:18 +01:00
let ( aMax , sMax ) = maxInSight $ parse content
print sMax
2019-12-11 02:20:24 +01:00
let newlist =
listCycle $
sort $
sortOn ( dist . fromJust ) $
snd $ transformCoordinates ( parse content ) aMax
let newnewlist = snd $ transformCoordinates newlist ( neg aMax )
print $ newnewlist !! 199
2019-12-10 21:21:20 +01:00
listCycle :: [ Maybe Asteroid ] -> [ Maybe Asteroid ]
listCycle [] = []
listCycle xs = nub xs ++ listCycle ( xs \\ nub xs )
parse :: [ String ] -> [ Maybe Asteroid ]
2019-12-11 02:20:24 +01:00
parse =
concat .
V . toList . V . map V . toList . toAsteroids . V . map V . fromList . V . fromList
where
toAsteroids = V . imap g
g x = V . imap ( f x )
f i j a =
case a of
'.' -> Nothing
_ -> Just $ Asteroid j i
transformCoordinates ::
[ Maybe Asteroid ] -> Asteroid -> ( Asteroid , [ Maybe Asteroid ] )
transformCoordinates xs a = ( a , [ Just $ x -| a | Just x <- xs , x /= a ] )
2019-12-10 21:21:20 +01:00
maxInSight :: [ Maybe Asteroid ] -> ( Asteroid , Int )
2019-12-11 02:20:24 +01:00
maxInSight xs =
maximumBy ( comparing snd ) $ map ( f . transformCoordinates xs ) ( catMaybes xs )
where
2019-12-14 15:56:18 +01:00
f ( x , y ) = ( x , length . nub $ y )