Skip to content

Commit c1e32bf

Browse files
committed
Solve day 14 part 1
1 parent a9ac8e2 commit c1e32bf

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

day14/src/Day14.hs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import System.Environment (getArgs)
44
import System.IO (readFile')
55
import Data.List (sort)
6+
import qualified Data.Set as S
67
import Control.Monad (join)
78

89
-- | Splits on the given value.
@@ -13,10 +14,14 @@ split x (y:ys) | x == y = [] : split x ys
1314
split _ [] = [[]]
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

5459
boardSize :: Vec2 Int
55-
boardSize = Vec2 11 7
60+
boardSize = Vec2 101 103
5661

5762
step :: Robot -> Robot
5863
step r = Robot ((r.pos .+. r.vel) .%. boardSize) r.vel
@@ -61,9 +66,10 @@ stepN :: Int -> Robot -> Robot
6166
stepN n = (!!% n) . period step
6267

6368
safetyFactor :: [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

6874
pretty :: [Robot] -> String
6975
pretty 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

Comments
 (0)