You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('') and can be up to 35 characters long.
90 lines
2.6 KiB
90 lines
2.6 KiB
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 = calculateMoons moons 1000


let ernergy = sum $ map getErnergy newMoons


let xAxis = getXAxis moons


let loopx = findLoop xAxis xAxis 0


let yAxis = getYAxis moons


let loopy = findLoop yAxis yAxis 0


let zAxis = getZAxis moons


let loopz = findLoop zAxis zAxis 0


let result = foldl1 lcm [loopx, loopy, loopz]


mapM putStrLn ( map show newMoons )


putStrLn ( show ernergy)


putStrLn(show result)




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)




gravity :: (Num a, Eq a)=> [a] > [a]


gravity xs = [sum [signum $ xy  x<xs, y/=x]  y<xs]




calculateMoons :: [Moon] > Int > [Moon]


calculateMoons xs 0 = xs


calculateMoons xs n = calculateMoons (stepGravity xs) (n1)




findLoop :: ([Int],[Int]) > ([Int],[Int]) > Int > Int


findLoop pos start c


 pos /= start  c == 0 = findLoop (stepAxis pos) start (c+1)


 pos == start = c




stepAxis :: ([Int],[Int]) > ([Int],[Int])


stepAxis (pos,vel) = (newPos, newVel)


where newVel = zipWith (+) (vel) (gravity pos)


newPos = zipWith (+) (pos) (newVel)




getPos :: [Moon] > [V3 Int]


getPos xs = map(\x > position x) xs




getVel :: [Moon] > [V3 Int]


getVel xs = map(\x > velocity x) xs




getErnergy :: Moon > Int


getErnergy (Moon pos vel) = (sum $ abs pos) * (sum $ abs vel)




getXAxis :: [Moon] > ([Int],[Int])


getXAxis xs = (pos,vel)


where pos = map(\x > getX $ position x) xs


vel = map(\x > getX $ velocity x) xs




getZAxis :: [Moon] > ([Int],[Int])


getZAxis xs = (pos,vel)


where pos = map(\x > getZ $ position x) xs


vel = map(\x > getZ $ velocity x) xs




getYAxis :: [Moon] > ([Int],[Int])


getYAxis xs = (pos,vel)


where pos = map(\x > getY $ position x) xs


vel = map(\x > getY $ velocity x) xs




getX :: V3 Int > Int


getX (V3 x y z) = x




getY :: V3 Int > Int


getY (V3 x y z) = y




getZ :: V3 Int > Int


getZ (V3 x y z) = z




