mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 05:49:52 +01:00
Add day12 part 1
This commit is contained in:
@@ -1,5 +1,61 @@
|
|||||||
module Day12 (day12) where
|
module Day12 (day12) where
|
||||||
|
|
||||||
|
import Data.List
|
||||||
|
import Data.List.Split
|
||||||
|
|
||||||
|
data V = V { _x :: Int, _y :: Int, _z :: Int } deriving (Eq, Show)
|
||||||
|
|
||||||
|
nullV :: V
|
||||||
|
nullV = V 0 0 0
|
||||||
|
|
||||||
|
data Moon = Moon { _pos :: V, _vel :: V } deriving (Eq, Show)
|
||||||
|
|
||||||
|
parseLine :: String -> Moon
|
||||||
|
parseLine input = Moon (V (getNb 0) (getNb 1) (getNb 2)) nullV
|
||||||
|
where input' = filter (\c -> not $ elem c "<>,") input
|
||||||
|
parts = splitOn " " input'
|
||||||
|
getNb x = read $ (!! 1) $ splitOn "=" $ (parts !! x)
|
||||||
|
|
||||||
|
computeVelocity :: V -> [Moon] -> V
|
||||||
|
computeVelocity pos@(V x y z) ((Moon (V ox oy oz) _):others) = V (curX + nextX) (curY + nextY) (curZ + nextZ)
|
||||||
|
where (V nextX nextY nextZ) = computeVelocity pos others
|
||||||
|
curX = veloChange x ox
|
||||||
|
curY = veloChange y oy
|
||||||
|
curZ = veloChange z oz
|
||||||
|
veloChange a b = if a > b
|
||||||
|
then -1
|
||||||
|
else if a < b
|
||||||
|
then 1
|
||||||
|
else 0
|
||||||
|
computeVelocity _ [] = nullV
|
||||||
|
|
||||||
|
applyVelocity :: [Moon] -> Moon -> Moon
|
||||||
|
applyVelocity others cur@(Moon curPos@(V px py pz) (V vx vy vz)) = Moon newPos newVel
|
||||||
|
where (V nvx nvy nvz) = computeVelocity curPos others'
|
||||||
|
others' = filter (/= cur) others
|
||||||
|
newVel = V (vx + nvx) (vy + nvy) (vz + nvz)
|
||||||
|
newPos = V (px + vx + nvx) (py + vy + nvy) (pz + vz + nvz)
|
||||||
|
|
||||||
|
computeStep :: [Moon] -> [Moon]
|
||||||
|
computeStep moons = map (applyVelocity moons) moons
|
||||||
|
|
||||||
|
moonEnergy :: Moon -> Int
|
||||||
|
moonEnergy (Moon (V px py pz) (V vx vy vz)) = potentialEnergy * kineticEnergy
|
||||||
|
where potentialEnergy = (abs px) + (abs py) + (abs pz)
|
||||||
|
kineticEnergy = (abs vx) + (abs vy) + (abs vz)
|
||||||
|
|
||||||
day12 :: IO ()
|
day12 :: IO ()
|
||||||
day12 = do
|
day12 = do
|
||||||
putStrLn "AoC 2019 day 12"
|
putStrLn "AoC 2019 day 12"
|
||||||
|
|
||||||
|
input <- getContents
|
||||||
|
|
||||||
|
let planets = map parseLine $ filter (not . null) $ splitOn "\n" input
|
||||||
|
let iteration = iterate computeStep planets
|
||||||
|
|
||||||
|
let at1000 = iteration !! 1000
|
||||||
|
putStrLn $ "Part 1: " ++ (show $ sum $ map moonEnergy $ at1000)
|
||||||
|
|
||||||
|
-- ok, inefficient, need something better
|
||||||
|
let idx = elemIndex planets $ tail iteration
|
||||||
|
putStrLn $ "Part 2: " ++ (show $ fmap (+1) idx)
|
||||||
|
|||||||
Reference in New Issue
Block a user