diff --git a/y2019/src/Day12.hs b/y2019/src/Day12.hs index d3b3311..58becb8 100644 --- a/y2019/src/Day12.hs +++ b/y2019/src/Day12.hs @@ -1,5 +1,61 @@ 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 = do 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)