Day 12: lcm is in Prelude :veryironicwow:

This commit is contained in:
shu 2019-12-12 13:23:54 +01:00
parent 457a7e7d73
commit b177b0daa5

View File

@ -1,6 +1,7 @@
import Data.List
import Data.List.Split
import Linear.V3
main :: IO ()
main = do
moons <- parseContent <$> readFile "input"
@ -30,9 +31,8 @@ step (moons, vel) = (zipWith (+) moons newVel, newVel)
newVel = zipWith (+) vel dVel
gravity xs = [sum [signum $ x - y | x <- xs, y /= x] | y <- xs]
part2 :: (Num a, Eq a) => ([[a]], [[a]]) -> Int
part2 (moons, vel) = lcm' periods
part2 (moons, vel) = foldr1 lcm periods
where
m = transpose moons
v = transpose vel
@ -46,30 +46,3 @@ findPeriod x a n =
else findPeriod x' a (n + 1)
where
x' = step x
lcm' :: [Int] -> Int
lcm' xs = product $ zipWith (^) nums maxElems
where
nums = nub $ concat decomp
decomp = map decomposition xs
maxElems = [maximum $ map (length . elemIndices x) decomp | x <- nums]
--hyper optimized prime decomposition
decomposition :: Int -> [Int]
decomposition 1 = []
decomposition x =
let n =
if x `mod` 2 == 0
then 2
else 3
maxiter = (floor . (sqrt :: Double -> Double) . fromIntegral) x
findprim candidate current
| (candidate <= maxiter) && (x `mod` candidate /= 0) =
findprim (next current) (current + 1)
| otherwise = candidate
m = findprim n 1
in if m <= maxiter
then m : decomposition (x `div` m)
else [x]
where
next k = k * 4 - k `div` 2 * 2 + 1