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.
89 lines
2.6 KiB
89 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 





