Skip to content

Instantly share code, notes, and snippets.

@ncfavier
Last active May 13, 2024 22:44
Show Gist options
  • Save ncfavier/a715e229abac653f75cf89c055d33d77 to your computer and use it in GitHub Desktop.
Save ncfavier/a715e229abac653f75cf89c055d33d77 to your computer and use it in GitHub Desktop.
import Data.Bits
import Data.Foldable
{-
Two implementations of A372325 (https://oeis.org/A372325).
The first one ties the knot on the sequence itself, but needs the first
three values in order to get bootstrapped.
Using a cleverer takeWhile we could produce the first 0, but in order to
produce 2 we need to know that 1 isn't in the sequence, which we only
know once we've seen 2.
-}
promisePrefix :: Eq a => [a] -> [a] -> [a]
promisePrefix [] xs = xs
promisePrefix (p:ps) ~(x:xs) = p : case x == p of True -> promisePrefix ps xs
a0 :: [Integer]
a0 = promisePrefix [0, 2, 5]
[n | n <- [0..], not (foldl' (\b i -> b `xor` testBit n (fromInteger i)) False (takeWhile (\i -> n >= 2^i) a0))]
{-
The second implementation ties the knot on the underlying stream of
booleans of the sequence (seen as a decidable subset of ℕ), and bootstraps itself.
-}
bits :: Integer -> [Bool]
bits 0 = []
bits n = testBit n 0 : bits (shiftR n 1)
a1 :: [Integer]
a1 = [n | (n, b) <- zip [0..] bs, b] where
bs :: [Bool]
bs = not . foldl' xor False . zipWith (&&) bs . bits <$> [0..]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment