2
2
3
3
import System.Environment (getArgs )
4
4
import System.IO (readFile' )
5
- import Data.List (sort )
5
+ import Data.List (findIndex )
6
6
import qualified Data.Set as S
7
7
import Control.Monad (join )
8
+ import Data.Maybe (fromJust )
8
9
9
10
-- | Splits on the given value.
10
11
split :: Eq a => a -> [a ] -> [[a ]]
@@ -55,6 +56,15 @@ step r = Robot ((r.pos .+. r.vel) .%. boardSize) r.vel
55
56
stepN :: Int -> Robot -> Robot
56
57
stepN n = (!! n) . iterate step
57
58
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
+
58
68
safetyFactor :: [Robot ] -> Int
59
69
safetyFactor rs = foldr1 (*) [length $ filter (\ p -> p. x `xop` center. x && p. y `yop` center. y) ps | (xop, yop) <- cartesianSquare [(<) , (>) ]]
60
70
where center = boardSize ./ 2
@@ -73,6 +83,11 @@ main = do
73
83
[path] -> do
74
84
raw <- readFile' path
75
85
let robots = parseRobot <$> lines raw
86
+ part1 = safetyFactor robots1
87
+ part2 = stepsUntil isChristmasTree robots
76
88
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
78
93
_ -> putStrLn " Usage: day14 <path to input>"
0 commit comments