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
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)
|
|
|