1
0
Fork 0
adventofcode/20.hs

43 lines
1.4 KiB
Haskell
Raw Normal View History

2017-12-20 07:13:25 +00:00
import Data.List.Split (splitOn)
import Data.List (elemIndex, sortOn, groupBy)
import Data.Monoid ((<>))
import Data.Function (on)
import Data.Vector.Class
import Data.Vector.V3
2017-12-20 07:13:25 +00:00
data Particle = Particle {
position :: Vector3,
velocity :: Vector3,
acceleration :: Vector3
2017-12-20 07:13:25 +00:00
}
instance Ord Vector3 where
Vector3 x1 y1 z1 `compare` Vector3 x2 y2 z2 = compare x1 x2 <> compare y1 y2 <> compare z1 z2
2017-12-20 07:13:25 +00:00
norm :: Vector3 -> Double
norm (Vector3 x y z) = abs x + abs y + abs z
2017-12-20 07:13:25 +00:00
updateParticle :: Double -> Particle -> Particle
2017-12-20 07:13:25 +00:00
updateParticle t (Particle p v a) =
Particle (p + t *| v + (t * (t + 1) / 2) *| a) (v + t *| a) a
2017-12-20 07:13:25 +00:00
stepParticles :: [Particle] -> [Particle]
stepParticles particles =
concat . filter ((== 1) . length) . groupBy ((==) `on` position) . sortOn position . map (updateParticle 1) $ particles
2017-12-20 07:13:25 +00:00
parseProperty :: String -> Vector3
2017-12-20 07:13:25 +00:00
parseProperty str =
let x : y : z : [] = map read . splitOn "," . drop 3 . init $ str
in Vector3 x y z
2017-12-20 07:13:25 +00:00
parseLine :: String -> Particle
parseLine str =
let p : v : a : [] = map parseProperty . splitOn ", " $ str
in Particle p v a
main :: IO ()
main = do
particles <- map parseLine . lines <$> readFile "20.txt"
let distances = map (norm . position . updateParticle 400) particles
2017-12-20 07:13:25 +00:00
print $ elemIndex (minimum distances) distances
print $ length $ iterate stepParticles particles !! 40