67 lines
2.4 KiB
Haskell
67 lines
2.4 KiB
Haskell
import Data.List as List
|
|
import Debug.Trace as Trace
|
|
|
|
main = do
|
|
content <- getContents
|
|
let layers = lines content
|
|
let indexlayers = map(\x-> mapInd(\x y -> (y,x)) x ) layers
|
|
let points = concat (mapInd(\x y->map(\x->((fst x,y),snd x))x) $ indexlayers)
|
|
let asteroids = (map fst (filter(\(x,y) -> y == '#' ) points))
|
|
let maximum = List.maximum(map(\x-> length(getViews (changeCoordinate (asteroids) x))) (asteroids))
|
|
let station = head $ map(\x-> fst x) $ filter(\x-> snd x == maximum )(map(\x-> (x,( length(getViews (changeCoordinate asteroids x))))) (asteroids))
|
|
let changedAsteroids = changeCoordinate asteroids station
|
|
let sortedAsteroids = sortBy sortDistance changedAsteroids
|
|
let views = getViews sortedAsteroids
|
|
let sortedViews = sortBy sortDegree views
|
|
let destroyed = getDestroyOrder sortedAsteroids []
|
|
let destroyNormal = map (\(a,b)-> (((fst station) + a),((snd station) + b))) destroyed
|
|
putStrLn(show maximum)
|
|
putStrLn(show station)
|
|
putStrLn(show views)
|
|
putStrLn(show sortedViews)
|
|
putStrLn(show $ map degree destroyed)
|
|
putStrLn(show $ destroyNormal)
|
|
putStrLn(show $ destroyNormal!!199)
|
|
mapInd :: (a -> Int -> b) -> [a] -> [b]
|
|
mapInd f l = zipWith f l [0..]
|
|
|
|
getDestroyOrder :: [(Int,Int)] -> [(Int,Int)] -> [(Int,Int)]
|
|
getDestroyOrder ast out
|
|
| length ast > 0 = do
|
|
let views = getViews ast
|
|
let sortedViews = sortBy sortDegree views
|
|
let newout = out ++ sortedViews
|
|
let newast = ast \\ sortedViews
|
|
getDestroyOrder newast newout
|
|
| otherwise = out
|
|
|
|
sortDistance ((a,b)) ((a2,b2))
|
|
| abs(a) + abs(b) > abs(a2) + abs(b2) = GT
|
|
| abs(a) + abs(b) < abs(a2) + abs(b2) = LT
|
|
| abs(a) + abs(b) == abs(a2) + abs(b2) = EQ
|
|
|
|
sortDegree a b
|
|
| degree a < degree b = GT
|
|
| degree a > degree b = LT
|
|
| degree a == degree b = EQ
|
|
|
|
getViews :: [(Int,Int)] -> [(Int,Int)]
|
|
getViews xs = foldl getView [] xs
|
|
|
|
changeCoordinate :: [(Int, Int)] -> (Int,Int) -> [(Int,Int)]
|
|
changeCoordinate xs (a,b) = (delete (0,0)( (map(\(x,y) -> ((x-a),(y-b)))xs)))
|
|
|
|
getView :: [(Int,Int)] -> (Int,Int) -> [(Int,Int)]
|
|
getView xs y
|
|
|notElem (reduce y) (map reduce xs) = xs ++ [y]
|
|
|otherwise = xs
|
|
|
|
reduce :: (Int,Int) -> (Int,Int)
|
|
reduce (a,b) = ((div a (gcd a b)),(div b (gcd a b)))
|
|
|
|
degree :: (Int,Int) -> Double
|
|
degree (a,b) = do
|
|
let x = fromIntegral a
|
|
let y = fromIntegral b
|
|
atan2 x (y)
|