mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 22:09:50 +01:00
Merge AoC 2019 & 2020 Haskell codebases
This commit is contained in:
55
haskellAoC/src/Y2019/Day10.hs
Normal file
55
haskellAoC/src/Y2019/Day10.hs
Normal file
@@ -0,0 +1,55 @@
|
||||
module Y2019.Day10 (day10) where
|
||||
|
||||
import Data.List
|
||||
import Geo.Vector
|
||||
import Geo.Point
|
||||
|
||||
parseLine :: Int -> [Char] -> [Int]
|
||||
parseLine xp ('#':cs) = xp:(parseLine (xp + 1) cs)
|
||||
parseLine xp (_:cs) = parseLine (xp + 1) cs
|
||||
parseLine _ [] = []
|
||||
|
||||
parseInput :: Int -> [String] -> [Point]
|
||||
parseInput yp (l:ls) = (map convertToPoint $ parseLine 0 l) ++ parseInput (yp + 1) ls
|
||||
where convertToPoint xp = Point (fromIntegral xp) (fromIntegral yp)
|
||||
parseInput _ [] = []
|
||||
|
||||
getDirVectors :: Point -> [Point] -> [Vector]
|
||||
getDirVectors src (dest:dests) = computedVect:(getDirVectors src dests)
|
||||
where computedVect = roundVecAtN 5 $ directionalVectorFromPoint (dest `sub` src)
|
||||
getDirVectors _ [] = []
|
||||
|
||||
getVectorAndDistPerPoint :: [Point] -> Point -> [(Point, Double, Double)]
|
||||
getVectorAndDistPerPoint (dest:dests) src = (dest, computedVect, distance):nextEntries
|
||||
where computedVect = vec2angle $ directionalVectorFromPoint diffPt
|
||||
distance = roundN 5 $ sqrt $ ((Geo.Point.x diffPt) ^ 2) + ((Geo.Point.y diffPt) ^ 2)
|
||||
diffPt = dest `sub` src
|
||||
nextEntries = getVectorAndDistPerPoint dests src
|
||||
getVectorAndDistPerPoint [] _ = []
|
||||
|
||||
asteroidSorting :: (Point, Double, Double) -> (Point, Double, Double) -> Ordering
|
||||
asteroidSorting (_, angle1, dist1) (_, angle2, dist2)
|
||||
| angle1 > angle2 = GT
|
||||
| angle1 < angle2 = LT
|
||||
| dist1 > dist2 = GT
|
||||
| dist1 < dist2 = LT
|
||||
| otherwise = EQ
|
||||
|
||||
getLaserOrder :: [[Point]] -> [Point]
|
||||
getLaserOrder ((p:[]):xs) = p:(getLaserOrder xs)
|
||||
getLaserOrder ((p:ps):xs) = p:(getLaserOrder (xs ++ [ps]))
|
||||
getLaserOrder [] = []
|
||||
|
||||
day10 :: [String] -> (String, String)
|
||||
day10 input = (part1, part2)
|
||||
where asteroids = parseInput 0 input
|
||||
p1 = maximumBy (\(_, a) (_, b) -> compare a b) $ map countFn asteroids
|
||||
countFn pt = (pt, (length $ nub $ getDirVectors pt asteroids) - 1)
|
||||
p2 = getLaserOrder $
|
||||
map (\m -> map (\(p, _, _) -> p) m) $
|
||||
groupBy (\(_, v1, _) (_, v2, _) -> v1 == v2) $
|
||||
sortBy asteroidSorting $
|
||||
getVectorAndDistPerPoint asteroids $
|
||||
fst p1
|
||||
part1 = show $ p1
|
||||
part2 = show $ p2 !! 200
|
||||
Reference in New Issue
Block a user