Add day12 part 1

This commit is contained in:
Xavier Morel
2019-12-22 15:46:46 +01:00
parent 324ffcbe83
commit e41632433c

View File

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