Пример #1
0
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
Пример #3
0
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 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
Пример #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)
Пример #6
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)
Пример #7
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
Пример #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
Пример #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
Пример #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)
Пример #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
Пример #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
Пример #13
0
def constant(n):
    """
    Constant Sequences: Returns n forever
    OEIS A000004, A000012, A007395, A010701
    """
    
    require_integers(["n"],[n])
    
    yield from repeat(n)
Пример #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)
Пример #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)
Пример #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)
Пример #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 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)
Пример #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))
Пример #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
Пример #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))
Пример #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)
Пример #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
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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
Пример #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