46 lines
1.3 KiB
Haskell
46 lines
1.3 KiB
Haskell
|
import Data.List.Split
|
||
|
import Data.List
|
||
|
import Data.Char as Char
|
||
|
import Linear.V3
|
||
|
|
||
|
main = do
|
||
|
moons <- map createMoon <$> map getList <$> map cleanString <$> lines <$> getContents
|
||
|
let newMoons = stepMoons moons 1000
|
||
|
let ernergy = sum $ map getErnergy newMoons
|
||
|
mapM putStrLn ( map show newMoons )
|
||
|
putStrLn ( show ernergy)
|
||
|
|
||
|
data Moon = Moon{ position :: V3 Int
|
||
|
,velocity :: V3 Int
|
||
|
} deriving Show
|
||
|
|
||
|
getList :: String -> [Int]
|
||
|
getList = map read . splitOn ", "
|
||
|
|
||
|
cleanString :: String -> String
|
||
|
cleanString xs = xs \\ "<>xyz==="
|
||
|
|
||
|
createMoon :: [Int] -> Moon
|
||
|
createMoon [x,y,z] = Moon (V3 x y z) (V3 0 0 0)
|
||
|
|
||
|
stepGravity :: [Moon] -> [Moon]
|
||
|
stepGravity xs = map (\(p,v) -> Moon p v) $ zip (newPos) newVel
|
||
|
where newVel = zipWith (+) (getVel xs) (gravity $ getPos xs)
|
||
|
newPos = zipWith (+) (getPos xs) (newVel)
|
||
|
|
||
|
getPos :: [Moon] -> [V3 Int]
|
||
|
getPos xs = map(\x -> position x) xs
|
||
|
|
||
|
getVel :: [Moon] -> [V3 Int]
|
||
|
getVel xs = map(\x -> velocity x) xs
|
||
|
|
||
|
gravity :: [V3 Int] -> [V3 Int]
|
||
|
gravity xs = [sum [signum $ x-y | x<-xs, y/=x] | y<-xs]
|
||
|
|
||
|
stepMoons :: [Moon] -> Int -> [Moon]
|
||
|
stepMoons xs 0 = xs
|
||
|
stepMoons xs n = stepMoons (stepGravity xs) (n-1)
|
||
|
|
||
|
getErnergy :: Moon -> Int
|
||
|
getErnergy (Moon pos vel) = (sum $ abs pos) * (sum $ abs vel)
|