33import System.Environment (getArgs )
44import System.IO (readFile' )
55import Data.List (sort )
6+ import qualified Data.Set as S
67import Control.Monad (join )
78
89-- | Splits on the given value.
@@ -13,10 +14,14 @@ split x (y:ys) | x == y = [] : split x ys
1314split _ [] = [[] ]
1415
1516-- | Finds the period of the given function.
16- period :: Eq a => (a -> a ) -> a -> [a ]
17- period f = period' []
18- where period' acc x | x `elem` acc = reverse acc
19- | otherwise = period' (x : acc) (f x)
17+ period :: Ord a => (a -> a ) -> a -> [a ]
18+ period f = period' S. empty
19+ where period' acc x | x `S.member` acc = []
20+ | otherwise = x : period' (S. insert x acc) (f x)
21+
22+ -- | The cartesian product with itself.
23+ cartesianSquare :: [a ] -> [(a , a )]
24+ cartesianSquare xs = [(x, x') | x <- xs, x' <- xs]
2025
2126-- | Finds the nth element of the list (modulo the list's length) .
2227(!!%) :: [a ] -> Int -> a
@@ -52,7 +57,7 @@ parseRobot raw = Robot pos vel
5257 where [pos, vel] = parseVec2 . drop 2 <$> split ' ' raw
5358
5459boardSize :: Vec2 Int
55- boardSize = Vec2 11 7
60+ boardSize = Vec2 101 103
5661
5762step :: Robot -> Robot
5863step r = Robot ((r. pos .+. r. vel) .%. boardSize) r. vel
@@ -61,9 +66,10 @@ stepN :: Int -> Robot -> Robot
6166stepN n = (!!% n) . period step
6267
6368safetyFactor :: [Robot ] -> Int
64- safetyFactor rs = length . filter inQuadrant $ ( . pos) <$> rs
69+ safetyFactor rs = foldr1 (*) [ length $ filter ( \ p -> p . x `xop` center . x && p . y `yop` center . y) ps | (xop, yop) <- cartesianSquare [ (<) , (>) ]]
6570 where center = boardSize ./ 2
6671 inQuadrant v = v. x /= center. x || v. y /= center. y
72+ ps = filter inQuadrant $ (. pos) <$> rs
6773
6874pretty :: [Robot ] -> String
6975pretty rs = unlines $ (\ y -> join $ (\ x -> showCount . length . filter (== Vec2 x y) $ (. pos) <$> rs) <$> [0 .. boardSize. x]) <$> [0 .. boardSize. y]
@@ -78,6 +84,5 @@ main = do
7884 raw <- readFile' path
7985 let robots = parseRobot <$> lines raw
8086 robots1 = stepN 100 <$> robots
81- putStrLn $ pretty robots1
8287 putStrLn $ " Part 1: " ++ show (safetyFactor robots1)
8388 _ -> putStrLn " Usage: day14 <path to input>"
0 commit comments