Skip to main content
Tweeted twitter.com/StackCodeReview/status/1394488063422877696

I wrote a function to return the first n length sequence which occurs twice in the digits of pi. Along with the repeated sequence, I want the indices of the first and second occurrences. For example, if n is 11, code returns (1, 0, 2)(1, 0, 2) and if n is 2, (26, 52, 20)(26, 5, 20). 

For reference, here are the first digits of pi,:

3.141592653589793238462643383279502884197169399375105820974944592...

The code uses a breadth-first search (as opposed to a depth-first search, which I coded up to be faster, but isn't what I'm looking for). I realize code below is convoluted and inefficient because it checks same digits multiple times.

How do I make it simpler and faster?

code

from mpmath import mp

mp.dps = 1000
pi = mp.pi

def repeats(n):
    pi_list = [int(x) for x in str(pi)[2:]]
    breadth = range(n + n, len(pi_list))
    
    for breadth_level in breadth:
        
        pattern_starts = range(breadth_level - 2 * n + 1)
        for p_s in pattern_starts:
            
            test_starts = range(n, breadth_level - n + 1)
            for t_s in test_starts:
                candidate = pi_list[p_s:p_s + n]
                test_start = max(p_s + n, t_s)
                test = pi_list[test_start:test_start + n]
                if candidate == test:
                    return candidate, p_s, t_s

print(repeats(1))
print(repeats(2))
print(repeats(3))

output

([1], 0, 2)
([2, 6], 5, 20)
([5, 9, 2], 3, 60)

I wrote a function to return the first n length sequence which occurs twice in the digits of pi. Along with the repeated sequence, I want the indices of the first and second occurrences. For example, if n is 1, code returns (1, 0, 2) and if n is 2, (26, 5, 20). For reference, here are the first digits of pi,

3.141592653589793238462643383279502884197169399375105820974944592...

The code uses a breadth-first search (as opposed to a depth-first search, which I coded up to be faster, but isn't what I'm looking for). I realize code below is convoluted and inefficient because it checks same digits multiple times.

How do I make it simpler and faster?

code

from mpmath import mp

mp.dps = 1000
pi = mp.pi

def repeats(n):
    pi_list = [int(x) for x in str(pi)[2:]]
    breadth = range(n + n, len(pi_list))
    
    for breadth_level in breadth:
        
        pattern_starts = range(breadth_level - 2 * n + 1)
        for p_s in pattern_starts:
            
            test_starts = range(n, breadth_level - n + 1)
            for t_s in test_starts:
                candidate = pi_list[p_s:p_s + n]
                test_start = max(p_s + n, t_s)
                test = pi_list[test_start:test_start + n]
                if candidate == test:
                    return candidate, p_s, t_s

print(repeats(1))
print(repeats(2))
print(repeats(3))

output

([1], 0, 2)
([2, 6], 5, 20)
([5, 9, 2], 3, 60)

I wrote a function to return the first n length sequence which occurs twice in the digits of pi. Along with the repeated sequence, I want the indices of the first and second occurrences. For example, if n is 1, code returns (1, 0, 2) and if n is 2, (26, 5, 20). 

For reference, here are the first digits of pi:

3.141592653589793238462643383279502884197169399375105820974944592...

The code uses a breadth-first search (as opposed to a depth-first search, which I coded up to be faster, but isn't what I'm looking for). I realize code below is convoluted and inefficient because it checks same digits multiple times.

How do I make it simpler and faster?

code

from mpmath import mp

mp.dps = 1000
pi = mp.pi

def repeats(n):
    pi_list = [int(x) for x in str(pi)[2:]]
    breadth = range(n + n, len(pi_list))
    
    for breadth_level in breadth:
        
        pattern_starts = range(breadth_level - 2 * n + 1)
        for p_s in pattern_starts:
            
            test_starts = range(n, breadth_level - n + 1)
            for t_s in test_starts:
                candidate = pi_list[p_s:p_s + n]
                test_start = max(p_s + n, t_s)
                test = pi_list[test_start:test_start + n]
                if candidate == test:
                    return candidate, p_s, t_s

print(repeats(1))
print(repeats(2))
print(repeats(3))

output

([1], 0, 2)
([2, 6], 5, 20)
([5, 9, 2], 3, 60)
update formatting
Source Link

I wrote a function to return the first n length sequence which occurs twice in the digits of pi. Along with the repeated sequence, I want the indices of the first and second occurrences. For example, if n is 1, code returns (1, 0, 2) and if n is 2, (26, 5, 20). For reference, here are the first digits of pi,

3.141592653589793238462643383279502884197169399375105820974944592...

3.141592653589793238462643383279502884197169399375105820974944592...

The code uses a breadth-first search (as opposed to a depth-first search, which I coded up to be faster, but isn't what I'm looking for). I realize code below is convoluted and inefficient because it checks same digits multiple times.

How do I make it simpler and faster?

code

from mpmath import mp

mp.dps = 1000
pi = mp.pi

def repeats(n):
    pi_list = [int(x) for x in str(pi)[2:]]
    breadth = range(n + n, len(pi_list))
    
    for breadth_level in breadth:
        
        pattern_starts = range(breadth_level - 2 * n + 1)
        for p_s in pattern_starts:
            
            test_starts = range(n, breadth_level - n + 1)
            for t_s in test_starts:
                candidate = pi_list[p_s:p_s + n]
                test_start = max(p_s + n, t_s)
                test = pi_list[test_start:test_start + n]
                if candidate == test:
                    return candidate, p_s, t_s

print(repeats(1))
print(repeats(2))
print(repeats(3))

([1], 0, 2)

([2, 6], 5, 20)

output

([5, 9, 2], 3, 60)

([1], 0, 2)
([2, 6], 5, 20)
([5, 9, 2], 3, 60)

I wrote a function to return the first n length sequence which occurs twice in the digits of pi. Along with the repeated sequence, I want the indices of the first and second occurrences. For example, if n is 1, code returns (1, 0, 2) and if n is 2, (26, 5, 20). For reference, here are the first digits of pi,

3.141592653589793238462643383279502884197169399375105820974944592...

The code uses a breadth-first search (as opposed to a depth-first search, which I coded up to be faster, but isn't what I'm looking for). I realize code below is convoluted and inefficient because it checks same digits multiple times.

How do I make it simpler and faster?

from mpmath import mp

mp.dps = 1000
pi = mp.pi

def repeats(n):
    pi_list = [int(x) for x in str(pi)[2:]]
    breadth = range(n + n, len(pi_list))
    
    for breadth_level in breadth:
        
        pattern_starts = range(breadth_level - 2 * n + 1)
        for p_s in pattern_starts:
            
            test_starts = range(n, breadth_level - n + 1)
            for t_s in test_starts:
                candidate = pi_list[p_s:p_s + n]
                test_start = max(p_s + n, t_s)
                test = pi_list[test_start:test_start + n]
                if candidate == test:
                    return candidate, p_s, t_s

print(repeats(1))
print(repeats(2))
print(repeats(3))

([1], 0, 2)

([2, 6], 5, 20)

([5, 9, 2], 3, 60)

I wrote a function to return the first n length sequence which occurs twice in the digits of pi. Along with the repeated sequence, I want the indices of the first and second occurrences. For example, if n is 1, code returns (1, 0, 2) and if n is 2, (26, 5, 20). For reference, here are the first digits of pi,

3.141592653589793238462643383279502884197169399375105820974944592...

The code uses a breadth-first search (as opposed to a depth-first search, which I coded up to be faster, but isn't what I'm looking for). I realize code below is convoluted and inefficient because it checks same digits multiple times.

How do I make it simpler and faster?

code

from mpmath import mp

mp.dps = 1000
pi = mp.pi

def repeats(n):
    pi_list = [int(x) for x in str(pi)[2:]]
    breadth = range(n + n, len(pi_list))
    
    for breadth_level in breadth:
        
        pattern_starts = range(breadth_level - 2 * n + 1)
        for p_s in pattern_starts:
            
            test_starts = range(n, breadth_level - n + 1)
            for t_s in test_starts:
                candidate = pi_list[p_s:p_s + n]
                test_start = max(p_s + n, t_s)
                test = pi_list[test_start:test_start + n]
                if candidate == test:
                    return candidate, p_s, t_s

print(repeats(1))
print(repeats(2))
print(repeats(3))

output

([1], 0, 2)
([2, 6], 5, 20)
([5, 9, 2], 3, 60)
Source Link
cona
  • 83
  • 4

Find the first repeating sequence in digits of pi

I wrote a function to return the first n length sequence which occurs twice in the digits of pi. Along with the repeated sequence, I want the indices of the first and second occurrences. For example, if n is 1, code returns (1, 0, 2) and if n is 2, (26, 5, 20). For reference, here are the first digits of pi,

3.141592653589793238462643383279502884197169399375105820974944592...

The code uses a breadth-first search (as opposed to a depth-first search, which I coded up to be faster, but isn't what I'm looking for). I realize code below is convoluted and inefficient because it checks same digits multiple times.

How do I make it simpler and faster?

from mpmath import mp

mp.dps = 1000
pi = mp.pi

def repeats(n):
    pi_list = [int(x) for x in str(pi)[2:]]
    breadth = range(n + n, len(pi_list))
    
    for breadth_level in breadth:
        
        pattern_starts = range(breadth_level - 2 * n + 1)
        for p_s in pattern_starts:
            
            test_starts = range(n, breadth_level - n + 1)
            for t_s in test_starts:
                candidate = pi_list[p_s:p_s + n]
                test_start = max(p_s + n, t_s)
                test = pi_list[test_start:test_start + n]
                if candidate == test:
                    return candidate, p_s, t_s

print(repeats(1))
print(repeats(2))
print(repeats(3))

([1], 0, 2)

([2, 6], 5, 20)

([5, 9, 2], 3, 60)