0

Okay so background: I'm solving a question which requires me to find a number 'n' such that n-9, n-3, n+3, n+9 are consecutive prime numbers and n-8, n-4, n+4, n+8 are practical numbers and then I have to add the first four n that satisfy this condition.

The problem: Whether the logic of the code is correct or incorrect is irrelevant here because my code crashes before it reaches 100 million. I can't even check the output of the code, it works fine for 1million but doesn't scale to well for larger numbers.

What i did: I used the sieve of erath... to get the prime numbers up to 100 million which we will call M. And since practical numbers are divisible by 6 or by 4, I created another set to store those numbers and from that list i then created a set that contained the numbers that satisfy this condition: 'n-8, n-4, n+4, n+8 are practical numbers' which we will call N. Finally I iterate through each element, a, in N and check whether a - 9, a - 3, a + 3, a + 9 are part of the prime number set.

If anyone has any tips on how i can speed this up or any better algorithms it would be greatly appreciated

code

def SieveOfEratosthenes(n):
    m = set()
    prime = [True for i in range(n + 1)]
    p = 2
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    prime[0]= False
    prime[1]= False
    for p in range(n + 1):
        if prime[p]:
            m.add(p)
    return m

#creates set that stores multiples of 4 and 6

def ps1(n):
    s = set()
    for i in range(1, n+1):
        if i%4 == 0 and i%6 == 0:
            s.add(i)
    return s

#checks whether any number satisfies n -8, n-4, n+4, n+8 must be practical and stores it in a set

def ps2(l):
    q = set()
    for i in l:
        if ((i-8) in l) and ((i-4) in l) and ((i+4) in l) and ((i+8) in l):
            q.add(i)
    return q

#using the numbers stored in the prev set, i check the last condition n-9, n-3, n+3, n+9 must be in the 
prime list
def TotalSieve(k, l):
    q = set()
    inc = 0
    for i in k:
        if inc != 4:
            if ((i-9) in l) and ((i-3) in l) and ((i+3) in l) and ((i+9) in l):
                inc = inc + 1
                q.add(i)
        else:
            print("Found 4")
    return q
                                                                       
# driver program
if __name__=='__main__':
    n = 1000000000
    m = SieveOfEratosthenes(n)
    p = ps1(n)
    p = ps2(p)
    f = TotalSieve(p, m)
    elem1 = f.pop()
    elem2 = f.pop()
    elem3 = f.pop()
    elem4 = f.pop()
#add the first four numbers that satisfy the conditions
    tot = elem1 + elem2 + elem3 + elem4
    print(tot)
    
JerSci
  • 89
  • 8
  • 1
    Is your issue that it 'crashes before it reaches 100 million' or that it is too slow? – miquelvir Mar 29 '21 at 19:14
  • @miquelvir it's both, 100 million takes a really long time for me, and then after a while, of a sudden i can hear my laptop speed up and my entire screen ends freezing then crashing. It only happens when i run this code, for 1 million it works just fine. – JerSci Mar 29 '21 at 19:22
  • You could to a multiprocessing; if you are able to divide the problem into different parts each processor can compute a part of it. Read [this](https://realpython.com/python-concurrency/#how-to-speed-up-a-cpu-bound-program). – miquelvir Mar 29 '21 at 19:25
  • @miquelvir i considered that but the problem can be solved around 1 minute without multiprocessing so i was hoping for a code optimization – JerSci Mar 29 '21 at 19:32
  • let's see if someone can help you with that! – miquelvir Mar 29 '21 at 19:36
  • 3
    Don't store all the numbers, just generate primes on the fly and keep what you need (at most the primes between N-18 and N). Check the conditions on primes, and if it is satisfied, the one on practical numbers. We have nice answers to build infinite generators of primes at https://stackoverflow.com/questions/2211990/how-to-implement-an-efficient-infinite-generator-of-prime-numbers-in-python – Thierry Lathuille Mar 29 '21 at 19:43
  • How much RAM do you have? How much RAM was the program using when it crashed? How much "swap" do you have? – Rick James Mar 31 '21 at 22:46
  • I have 8gb of ram and it almost jumped to 100% ram usage. I don't know wht swap means – JerSci Apr 01 '21 at 14:19
  • the numpy package may be of help – pqans Apr 13 '21 at 12:56

1 Answers1

1

First, ps1 is wrong. The test should say or, not and.

Next, if n is divisible by 4, all n-8, n-4, n+4, n+8 are also divisible by 4. If n is not divisible by 4, none of them are divisible by 4, and some of them are also not divisible by 4. Which means you are only interested in n being a multiple of 4.

Finally, I know that this problem implies some serious number-theoretical homework. Brute force wouldn't do it.

user58697
  • 6,907
  • 1
  • 11
  • 24