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
示例#2
0
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
示例#4
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
示例#5
0
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
示例#6
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
示例#7
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)
示例#8
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)
示例#9
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
示例#10
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
示例#11
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)
示例#12
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)
示例#13
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)
示例#14
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)
示例#15
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)
示例#16
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))
示例#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)
示例#18
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))
示例#19
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)
示例#20
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
示例#21
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)
示例#22
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)
示例#23
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)
示例#24
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
示例#25
0
def multi_fibonacci(n):
    """
    Higher Order Fibonacci Sequences\n
    OEIS A000073, A000078, A001591, A001592
    """
    
    require_integers(["n"],[n])
    require_geq(["n"],[n],2)
    
    S = [0]*(n-1)+[1]
    
    while True:
        yield S[0]
        S = S[1:] + [sum(S)]
示例#26
0
def plaindrome(B=10):
    """
    Plaindrome Numbers: Non-negative integers with their digits nondecreasing in base B\n
    OEIS
    """

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

    yield 0

    for n in naturals(1):
        if _plaindrome(n, B):
            yield n
示例#27
0
def collatz(n):
    """
    Collatz Sequence of n: Iteratively apply the Collatz function to n\n
    OEIS
    """
    
    require_integers(["n"],[n])
    require_geq(["n"],[n],1)
    
    yield n
    
    while n != 1:
        n = _collatz_step(n)
        yield n
示例#28
0
def reduced_collatz_sequence(n):
    """
    Reduced Collatz Sequence of n: Iteratively apply the Collatz function to n but with an addition division by 2 for odd numbers\n
    OEIS
    """
    
    require_integers(["n"],[n])
    require_geq(["n"],[n],1)
    
    yield n
    
    while n != 1:
        n = _reduced_collatz_step(n)
        yield n
示例#29
0
def powers(n):
    """
    Powers of n: Special case of geometric
    
    Args:
        n -- constant multiple
        
    OEIS A000079, A000244, A000302, A000351, A000400, A000420, A001018-A001027, 
         A001029, A009964-A009992, A011557, A159991, A165800
    """
    
    require_integers(["n"],[n])
    require_geq(["n"],[n],0)
    
    yield from geometric(1,n)
示例#30
0
def plaindrome_digits(B=10):
    """
    Plaindrome Numbers: Non-negative integers with their digits nondecreasing in base B\n
    OEIS
    """

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

    yield (0, )

    for n in naturals(1):
        p = _plaindrome(n, B)
        if p:
            yield tuple(p)