About to try optimising my version
authorNeil Smith <neil.git@njae.me.uk>
Fri, 15 Dec 2017 13:34:00 +0000 (13:34 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Fri, 15 Dec 2017 13:34:00 +0000 (13:34 +0000)
src/advent15/advent15.hs
src/advent15/advent15other.hs

index 6ee03c04cf0c6a6b53cefd98d10cc954cd772c3a..84e2412f7d8cb78219606b03a04f58dd67e06765 100644 (file)
@@ -23,14 +23,14 @@ generatorB = generator 2147483647 48271
 streamA = stream generatorA generatorAStart
 streamB = stream generatorB generatorBStart
 
-generator :: Word64 -> Word64 -> Word64 -> Word64
+generator :: Int -> Int -> Int -> Int
 generator divisor factor n = n * factor `rem` divisor
 
-toWord16 :: Word64 -> Word16
+toWord16 :: Int -> Word16
 toWord16 = fromIntegral
 
-stream :: (Word64 -> Word64) -> Word64 -> [Word16]
+stream :: (Int -> Int) -> Int -> [Word16]
 stream gen n0 = map toWord16 $ drop 1 $ iterate gen n0
 
 filteredStream :: Word16 -> [Word16] -> [Word16]
-filteredStream f str = filter ((== 0) . ( .&. f)) str
+filteredStream f = filter ((== 0) . ( .&. f))
index 0802707f1234a57e9c31d2587c0155073198cc95..5f0459c16af6a6b549006b54c6e912b06b82b1d3 100644 (file)
@@ -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