X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=src%2Fadvent15%2Fadvent15other.hs;h=5f0459c16af6a6b549006b54c6e912b06b82b1d3;hb=2d5d9af08576f1faa48347726b6fa4296b363674;hp=0802707f1234a57e9c31d2587c0155073198cc95;hpb=df0593061898494af0b96bf6a620d8efdda2fe0c;p=advent-of-code-17.git diff --git a/src/advent15/advent15other.hs b/src/advent15/advent15other.hs index 0802707..5f0459c 100644 --- a/src/advent15/advent15other.hs +++ b/src/advent15/advent15other.hs @@ -9,7 +9,7 @@ import Data.List (stripPrefix) import Data.Word (Word64) -- | Returns the initial values for generators A and B. -parse :: String -> (Word64, Word64) +-- parse :: String -> (Word64, Word64) parse _ = (873, 583) -- parse input = (read a, read b) where -- [line1, line2] = lines input @@ -23,40 +23,58 @@ main = do print $ day15b "none" --- | One step of generator A. -genA :: Word64 -> Word64 -genA x = x * 16807 `mod` 2147483647 --- | One step of generator B. -genB :: Word64 -> Word64 +genA, genB :: Int -> Int +genA x = x * 16807 `mod` 2147483647 genB x = x * 48271 `mod` 2147483647 --- | Step generator A until a multiple of 4. -genA' :: Word64 -> Word64 -genA' x = let y = genA x in if y .&. 3 == 0 then y else genA' y +day15a :: String -> Int +day15a input = length . filter id . take 40000000 $ zipWith (==) a b where + (a0, b0) = parse input + a = map (.&. 0xffff) $ iterate genA a0 + b = map (.&. 0xffff) $ iterate genB b0 --- | Step generator A until a multiple of 8. -genB' :: Word64 -> Word64 -genB' x = let y = genB x in if y .&. 7 == 0 then y else genB' y +day15b :: String -> Int +day15b input = length . filter id . take 5000000 $ zipWith (==) a b where + (a0, b0) = parse input + a = map (.&. 0xffff) . filter ((== 0) . (`mod` 4)) $ iterate genA a0 + b = map (.&. 0xffff) . filter ((== 0) . (`mod` 8)) $ iterate genB b0 --- | One step of both generators A and B. -gen :: (Word64, Word64) -> (Word64, Word64) -gen = genA *** genB --- | Step both generators A and B until a multiple of 4 and 8 respectively. -gen' :: (Word64, Word64) -> (Word64, Word64) -gen' = genA' *** genB' +-- -- | One step of generator A. +-- genA :: Word64 -> Word64 +-- genA x = x * 16807 `mod` 2147483647 --- | prop> count p f x n == length (filter p . take n . tail $ iterate f x) -count :: (a -> Bool) -> (a -> a) -> a -> Int -> Int -count p f = count' 0 where - count' !k x 0 = k - count' !k x n = count' (if p y then k + 1 else k) y (n - 1) where y = f x +-- -- | One step of generator B. +-- genB :: Word64 -> Word64 +-- genB x = x * 48271 `mod` 2147483647 -day15a :: String -> Int -day15a input = - count (uncurry ((==) `on` (.&. 0xffff))) gen (parse input) 40000000 +-- -- | Step generator A until a multiple of 4. +-- genA' :: Word64 -> Word64 +-- genA' x = let y = genA x in if y .&. 3 == 0 then y else genA' y -day15b :: String -> Int -day15b input = - count (uncurry ((==) `on` (.&. 0xffff))) gen' (parse input) 5000000 +-- -- | Step generator A until a multiple of 8. +-- genB' :: Word64 -> Word64 +-- genB' x = let y = genB x in if y .&. 7 == 0 then y else genB' y + +-- -- | One step of both generators A and B. +-- gen :: (Word64, Word64) -> (Word64, Word64) +-- gen = genA *** genB + +-- -- | Step both generators A and B until a multiple of 4 and 8 respectively. +-- gen' :: (Word64, Word64) -> (Word64, Word64) +-- gen' = genA' *** genB' + +-- -- | prop> count p f x n == length (filter p . take n . tail $ iterate f x) +-- count :: (a -> Bool) -> (a -> a) -> a -> Int -> Int +-- count p f = count' 0 where +-- count' !k x 0 = k +-- count' !k x n = count' (if p y then k + 1 else k) y (n - 1) where y = f x + +-- day15a :: String -> Int +-- day15a input = +-- count (uncurry ((==) `on` (.&. 0xffff))) gen (parse input) 40000000 + +-- day15b :: String -> Int +-- day15b input = +-- count (uncurry ((==) `on` (.&. 0xffff))) gen' (parse input) 5000000