22
33import System.Environment (getArgs )
44import System.IO (readFile' )
5- import Data.List (sort )
5+ import Data.List (findIndex )
66import qualified Data.Set as S
77import Control.Monad (join )
8+ import Data.Maybe (fromJust )
89
910-- | Splits on the given value.
1011split :: Eq a => a -> [a ] -> [[a ]]
@@ -55,6 +56,15 @@ step r = Robot ((r.pos .+. r.vel) .%. boardSize) r.vel
5556stepN :: Int -> Robot -> Robot
5657stepN n = (!! n) . iterate step
5758
59+ stepsUntil :: ([Robot ] -> Bool ) -> [Robot ] -> Int
60+ stepsUntil p = fromJust . findIndex p . iterate (step <$> )
61+
62+ -- Simple heuristic to check if all positions are unique.
63+ -- Not sure why this even works since the tree isn't the full input.
64+ isChristmasTree :: [Robot ] -> Bool
65+ isChristmasTree rs = S. size (S. fromList ps) == length rs
66+ where ps = (. pos) <$> rs
67+
5868safetyFactor :: [Robot ] -> Int
5969safetyFactor rs = foldr1 (*) [length $ filter (\ p -> p. x `xop` center. x && p. y `yop` center. y) ps | (xop, yop) <- cartesianSquare [(<) , (>) ]]
6070 where center = boardSize ./ 2
@@ -73,6 +83,11 @@ main = do
7383 [path] -> do
7484 raw <- readFile' path
7585 let robots = parseRobot <$> lines raw
86+ part1 = safetyFactor robots1
87+ part2 = stepsUntil isChristmasTree robots
7688 robots1 = stepN 100 <$> robots
77- putStrLn $ " Part 1: " ++ show (safetyFactor robots1)
89+ robots2 = stepN part2 <$> robots
90+ putStrLn $ " Part 1: " ++ show part1
91+ putStrLn $ " Part 2: " ++ show part2
92+ putStrLn $ pretty robots2
7893 _ -> putStrLn " Usage: day14 <path to input>"
0 commit comments