You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
2.4 KiB

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)