def strong_pseudoprimes(a):
    """
    Strong Pseudoprimes to Base a
    
    Args:
        a -- integer greater than 1
    
    OEIS
    """

    require_integers(["a"], [a])
    require_geq(["a"], [a], 2)

    for c in composites():
        if c % 2 == 1:
            d = c - 1
            r = 0

            d, r = factor_out_twos(d)

            if (a**d) % c == 1:
                yield c
                continue

            for e in range(0, r):
                if pow(a, (d * 2**e), c) == c - 1:
                    yield c
                    continue
def doubly_polygonal(S=2):
    """
    Doubly Polygonal Numbers: Polygonal numbers that 
    
    Args:
        S -- Number of sides
    
    OEIS A000583, A002817, A063249, A232713
    """

    require_integers(["S"], [S])
    require_geq(["S"], [S], 2)

    cur = 0
    P = polygonal(S)

    for s in polygonal(S):
        skip = s - cur - 1

        for n in range(skip):
            next(P)

        yield next(P)

        cur = s
def lucas_pseudoprimes(P, Q):
    """
    Lucas Pseudoprimes: Composite number passing the Lucas primality test for P and Q
    
    Args:
        P -- integer greater than zero
        Q -- integer
    
    OEIS
    """

    require_integers(["P", "Q"], [P, Q])
    require_geq(["P"], [P], 1)

    D = P * P - 4 * Q

    #rather than recompute we will step the sequence as needed
    lucas_pos = 0
    a, b = 0, 1

    for c in composites():
        if c % 2 == 1:
            if gcd(c, Q) == 1:
                delta = c - jacobi_symbol(D, c)

                if delta > lucas_pos:
                    for i in range(delta - lucas_pos):
                        a, b = b, P * b - Q * a

                    lucas_pos += delta - lucas_pos

                if a % c == 0:
                    yield c
Beispiel #4
0
def middle_square_weyl(n,k,m):
    """
    Middle Square Method Augmented with a Weyl Sequence
    
    Args:
        n -- seed value
        k -- initial value for Weyl Sequence
        m -- modulus of Weyl Sequence
    """
    
    # Only n has to be checked since the weyl() function will check k and m
    require_integers(["n"],[n])
    
    W = weyl(k,m)
    
    N = int_to_digits(n)
    width = len(N)+(len(N)%2)
    
    for w in W:
        a = n*n+w
        A = int_to_digits(a)
        
        if len(A) % 2 == 1:
            A = [0] + A
        
        n = digits_to_int(A[width//2:-width//2])
        
        yield n
Beispiel #5
0
def n_gap_prime_pairs(n):
    """
    Pairs of primes (p,q) such that p+n = q\n
    OEIS A077800, A156274, A156320, A140445, A156323, A140446, A272815, 
         A156328, A272816, A140447
    """

    require_integers(["n"], [n])
    require_geq(["n"], [n], 1)

    if n % 2 == 1:
        raise ValueError(
            "n must be even, for odd n either there is no pair or the only pair is (2,2+n)"
        )

    else:
        P = primes()
        lo = next(P)
        hi = [next(P)]

        while True:
            while hi[-1] < lo + n:
                hi.append(next(P))

            if lo + n in hi:
                yield (lo, lo + n)

            lo = hi.pop(0)
def pisot_E(a,b):
    """
    Pisot E-Sequence
    
    Args:
        a -- first term
        b -- second term
    
    OEIS A008776, A020701, A020720, A020707, A020706, A020695, A020729,
         A010904, A010916, A007699, A010900, A010903, A010912, A010914,
         A020711, A020717, A010901, A010902, A010905, A010907, A010911,
         A010913, A020708, A020721, A048575, A010908, A010909, A010910,
         A010915, A010917, A010924, A014001, A014002, A014003, A014004,
         A014005, A014006, A014007, A014008, A020704, A020709, A020712,
         A020713, A020716, A020718, A274951, A275628, A276396
    """
    
    require_integers(["a","b"],[a,b])
    require_geq(["a"],[a],1)
    
    if a >= b:
        raise ValueError("The first two terms of a Pisot sequence must be increasing")
    
    while True:
        yield a
        a,b = b,floor((b*b)/a + .5)
def pisot_T(a,b):
    """
    Pisot T-Sequence
    
    Args:
        a -- first term
        b -- second term
    
    OEIS A008776, A010925, A020707, A010919, A018919, A020729, A010920,
         A018921, A020742, A020745, A018914, A020746, A010922, A018915,
         A018917, A018918, A018920, A018922, A019492, A020747, A020748,
         A020749, A020750, A018923, A020728, A020732, A020741, A020744,
         A020751, A020752, A022034, A022039, A275904, A278681, A278692,
         A278764
    """
    
    require_integers(["a","b"],[a,b])
    require_geq(["a"],[a],1)
    
    if a >= b:
        raise ValueError("The first two terms of a Pisot sequence must be increasing")
    
    while True:
        yield a
        a,b = b,(b*b)//a
Beispiel #8
0
def root_digits(n, a, B=10):
    """
    Digits of the nth root of a in base B\n
    OEIS
    """

    require_integers(["a", "n", "B"], [a, n, B])
    require_geq(["a"], [a], 0)
    require_geq(["n", "B"], [n, B], 2)

    Bpow = B**n
    chunks = int_to_digits(a, Bpow)

    r, y = 0, 0

    for d in chain(chunks, constant(0)):
        c = Bpow * r + d
        x = 0

        for i in range(B):
            x += 1

            if (B * y + x)**n - (Bpow * y**n) > c:
                x -= 1
                break

        y1 = B * y + x
        r1 = c - ((B * y + x)**n - (Bpow * y**n))

        r, y = r1, y1

        yield x
Beispiel #9
0
def sqrt_digits(n, B=10):
    """
    Digits of the square root of n in base B\n
    OEIS A002193, A002194, A002163, A010465, A010466, A010467, A010464, 
         A010472, A010468, A010490, A010469, A010470, A010471, A010477,
         A010473, A010524, A010474
    """

    require_integers(["n", "B"], [n, B])
    require_geq(["n"], [n], 0)
    require_geq(["B"], [B], 2)

    Bsq = B * B
    p, r = 0, 0

    chunks = int_to_digits(n, Bsq)

    for d in chain(chunks, constant(0)):
        c = Bsq * r + d
        x = -1

        for i in range(B):
            x += 1

            if x * (x + (2 * B * p)) > c:
                x -= 1
                break

        r = c - x * (x + 2 * B * p)
        p = B * p + x

        yield x
Beispiel #10
0
def ordered_set_partitions(n,index=0):
    """
    The ordered partitions of a set with n elements
    """
    
    require_integers(["n","index"],[n,index])
    require_geq(["n"],[n],1)
    
    if index not in (0,1):
        raise Exception("index must be 0 or 1")
    
    def part(depth):
        if depth == index:
            yield ((index,),)
        else:
            for t in part(depth-1):
                for n,sub in enumerate(t):
                    yield t[:n] + (sub + (depth,),) + t[n+1:]
                yield t + ((depth,),)
                yield ((depth,),) + t
    
    if index == 1:
        yield from part(n)
    else:
        yield from part(n-1)
Beispiel #11
0
def palindrome(B=10):
    """
    Palindrome Numbers: Non-negative integers that are palindromes in base B\n
    OEIS A002113, A006995
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    if B == 10:
        for n in naturals():
            if str(n) == str(n)[::-1]:
                yield n

    else:
        for n in naturals():
            m = n
            d = []

            while n != 0:
                n, r = divmod(n, B)
                d.append(str(r))

            s = "".join(d)

            if s == s[::-1]:
                yield m
Beispiel #12
0
def blum_blum_shub(x,p,q):
    """
    Blum Blum Shub
    
    Args:
        x -- seed value, coprime to pq, and greater than 1
        p -- prime congruent to 3 mod 4
        q -- prime congruent to 3 mod 4
    """
    
    m = p*q
    
    require_integers(["x","p","q"], [x,p,q])
    require_prime( ["p","q"], [p,q])
    require_true(["p","q"], [p,q], lambda x: x % 4 == 3, "must be congruent to 3 mod 4")
    require_geq(["x"], [x], 2)
    K = legendre_symbol(2,(p-1)//2) + legendre_symbol(2,(q-1)//2)
    
    if K == 2:
        raise Exception("both (p-1)/2 and (q-1)/2 have 2 as a quadratic residue")
    
    if gcd(m,x) != 1:
        raise Exception("x must be coprime to pq")
    
    while True:
        yield x
        
        x = (x*x)%m
Beispiel #13
0
def constant(n):
    """
    Constant Sequences: Returns n forever
    OEIS A000004, A000012, A007395, A010701
    """
    
    require_integers(["n"],[n])
    
    yield from repeat(n)
Beispiel #14
0
def phi_digits(B=10):
    """
    Phi: Digits of the golden ratio in base B\n
    OEIS A001622
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    yield from metallic_ratio_digits(1, B)
Beispiel #15
0
def silver_ratio_digits(B=10):
    """
    Digits of the silver ratio in base B\n
    OEIS A014176
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    yield from metallic_ratio_digits(2, B)
Beispiel #16
0
def digital_roots(B=10):
    """
    Digital Roots: Final value of the iteration of digital sums of each non-negative integer in base b\n
    OEIS A010888
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    for n in naturals():
        yield digital_root(n, B)
Beispiel #17
0
def digital_prods(B=10):
    """
    Digital Sums: Sum of the digits of each non-negative integer in base B\n
    OEIS A007953
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    for n in naturals():
        yield digital_prod(n, B)
Beispiel #18
0
def lattice_language(k):
    """
    Lattice words using k symbols
    Every prefix of a word must contain at least as many instances of i as of i+1
    """
    
    require_integers(["k"],[k])
    require_geq(["k"],[k],1)
    
    for n in naturals(1):
        yield from lattice_words(n,k)
Beispiel #19
0
def fraction_period(B=10):
    """
    Repeating period of each unit fraction in base B\n
    OEIS A007732
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    for n in naturals(1):
        yield len(repeating_part(1, n, B))
Beispiel #20
0
def sign_sequence(n=1):
    """
    Sequence of +n and -n repeated forever\n
    OEIS A033999
    """
    
    require_integers(["n"],[n])
    
    while True:
        yield n
        yield -n
Beispiel #21
0
def champernowne_digits(B=10):
    """
    Digits of the base B version of Champernowne's constant\n
    OEIS A003137, A030302, A030548, A033307, A030373, A031219, A030998, 
         A031035, A031076
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    for n in naturals(1):
        yield from iter(int_to_digits(n, B))
Beispiel #22
0
def fuss_catalan(p,r):
    """
    Fuss-Catalan Numbers
    OEIS A000108, A000245, A002057, A001764, A006013, A006629, A002293, 
         A069271, A006632
    """
    
    require_integers(["p","r"],[p,r])
    require_geq(["p","r"],[p,r],0)
    
    for n in naturals():
        yield r*comb(n*p+r,n)//(n*p+r)
Beispiel #23
0
def dirichlet_terms(A,s):
    """
    Terms of the given Dirichlet series
    """
    
    require_integers(["s"], [s])
    require_geq(["s"], [s], 1)
    require_iterable(["A"],[A])
    
    for n,a in enumerate(A,1):
        f = Fraction(a)/Fraction(n**s)
        yield f
Beispiel #24
0
def radix_digits(B=10):
    """
    The digits of each natural number in base B\n
    OEIS
    """

    require_integers(["B"], [B])
    require_geq(["B"], [B], 2)

    yield (0, )

    for n in naturals(1):
        yield int_to_digits(n, B)
Beispiel #25
0
def arithmetic(a,n):
    """
    Arithmetic Sequences: Integers with constant difference
    
    Args:
        a -- starting value
        n -- common difference
    
    OEIS
    """
    
    require_integers(["a","n"],[a,n])
    
    yield from count(a,n)
Beispiel #26
0
def counting(offset=0):
    """
    Counting Numbers: Positive whole numbers, special case of arithmetic
    
    Args:
        offset -- nonnegative integer how many counting numbers to skip before starting
        
    OEIS A000027
    """
    
    require_integers(["offset"],[offset])
    require_geq(["offset"],[offset],0)
    
    yield from count(offset+1,1)
Beispiel #27
0
def naturals(offset=0):
    """
    Natural Numbers: Nonnegative whole numbers, special case of arithmetic
    
     Args:
        offset -- nonnegative integer how many naturals to skip before starting
        
    OEIS A001477
    """
    
    require_integers(["offset"],[offset])
    require_geq(["offset"],[offset],0)
    
    yield from count(offset,1)
Beispiel #28
0
def taylor_terms(A, c=0):
    """
    Coefficients of each term of the Talyor Series defined by the sequence A and constant c\n
    """

    require_iterable(["A"], [A])
    require_integers(["c"], [c])

    P = [1]

    for a in A:
        yield poly_mult([a], P)

        P = poly_mult([1, -c], P)
Beispiel #29
0
def taylor_sums(A, c=0):
    """
    Coefficients of each partial sum of the Talyor Series defined by the sequence A and constant c\n
    """

    require_iterable(["A"], [A])
    require_integers(["c"], [c])

    S = [0]

    for P in taylor_terms(A, c):
        S = poly_sum(P, S)

        yield S
Beispiel #30
0
def dirichlet_sums(A,s):
    """
    Partial Sums of the given Dirichlet series
    """
    
    require_integers(["s"], [s])
    require_geq(["s"], [s], 1)
    require_iterable(["A"],[A])
    
    p = Fraction(0)
    
    for f in dirichlet_terms(A,s):
        p += f
        yield p