-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay14.hs
38 lines (29 loc) · 1.22 KB
/
Day14.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
module Day14 (main) where
import Data.List (transpose, intercalate)
import Data.List.Split (splitOn)
roll :: [Char] -> [Char]
roll = intercalate "#" . map (\xs -> filter (== 'O') xs ++ filter (== '.') xs) . splitOn "#"
rollNorth, rollSouth, rollWest, rollEast :: [String] -> [String]
rollNorth = transpose . map roll . transpose
rollSouth = transpose . map (reverse . roll . reverse) . transpose
rollWest = map roll
rollEast = map (reverse . roll . reverse)
spin :: [String] -> [String]
spin = rollEast . rollSouth . rollWest . rollNorth
part2 :: Int -> [String] -> [String]
part2 reps input = spins !! (cycleSize - remainder - 1) where
(cycleSize, cycleStart, spins) = findRepeat [] input
remainder = (reps - cycleStart) `mod` cycleSize
findRepeat :: [[String]] -> [String] -> (Int, Int, [[String]])
findRepeat xss xs = case lookup xs (zip xss [1..]) of
Just i -> (i, length xss, xss)
Nothing -> findRepeat (xs:xss) (spin xs)
score :: [String] -> Int
score = sum . zipWith (*) [1..] . reverse . map (length . filter (== 'O'))
main :: IO ()
main = do
input <- lines <$> getContents
putStr "part 1: "
print $ score $ rollNorth input
putStr "part 2: "
print $ score $ part2 1000000000 input