@@ 19,13 19,13 @@ import qualified Data.Sequence as Seq
import qualified Data.Set as Set
data Rock = Round | Cube
- deriving ( Show, Eq )
+ deriving ( Show, Eq, Ord )
type Pos = (Int,Int)
type Bounds = (Pos, Pos)
data Grid a = Grid (Map.Map Pos a) Bounds
- deriving ( Show, Eq )
+ deriving ( Show, Eq, Ord )
parseGrid :: Parser (Maybe a) -> Parser (Grid a)
parseGrid p = do
@@ 109,17 109,20 @@ partA :: Parse -> Int
partA = load . tilt north
partB :: Parse -> Int
-partB = f 0
- where r Nothing = '.'
- r (Just Cube) = '#'
- r (Just Round) = 'O'
- f n g | n == 1000000000 = load g
- f n g | otherwise = f (succ n) (cycle g)
+partB g =
+ let (a, b) = f Map.empty 0 g in
+ let i = b + ((1_000_000_000 - b) `mod` (a-b)) in
+ load (idx i)
+ where idx i = flip (!!) i $ iterate cycle g
+ f vs n g =
+ case Map.lookup g vs of
+ Just n' -> (n, n')
+ Nothing -> f (Map.insert g n vs) (succ n) (cycle g)
cycle = tilt east . tilt south . tilt west . tilt north
main :: IO ()
main = with parser $ do
run' "14.example" "a example" partA 136
run' "14.input" "a input" partA 106378
- run "14.example" "b example" partB
- --run "14.input" "b input" partB
+ run' "14.example" "b example" partB 64
+ run' "14.input" "b input" partB 90795