0

This post is twofold. I am a neophyte to Python.

First part.

This is my code for the old Google puzzle: 'First 10 digit prime number in the consecutive digits of e' (https://google-tale.blogspot.ca/2008/07/google-billboard-puzzle.html)

euler = '7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354'


for i in range(len(euler) - 3):
    if (euler[i + 3]== '1' or euler[i + 3]== '3' or euler[i + 3]== '7' or euler[i + 3]== '9'):
        number = int(euler[i:i + 3])
        for a in range(2, round(number**0.5)):
           if number % a == 0:
             break
        else:
           print(number),
           break

So strangely using the code above I can find the correct answer which is 7427466391 (it takes 45mn to compile) but when I test the code for 3 digits it gives me 709 which is incorrect because the first 3-digits prime number is 281 range(3,6).

How can I fix this?

Second part.

This is an algorithm which is supposed to be the fastest to find a prime number (https://en.wikipedia.org/wiki/Primality_test) (see pseudo-code in the middle of the page). This is my code but it doesn't work, I enter into an infinite loop.

for i in range(len(euler) - 3):
    if (euler[i + 3]== '1' or euler[i + 3]== '3' or euler[i + 3]== '7' or euler[i + 3]== '9'):
        number = int(euler[i:i + 3])
        for y in range(2, number-1):
            while y * y <= number:
                if (number % y != 0 or  number % (y+1) != 0):
                break

How can I fix it?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Alan
  • 157
  • 8

2 Answers2

1

For the first part, replace '3' with '2' so that it checks the 3rd digit for oddness, instead of the 4th:

euler[i + 3]== '1' or euler[i + 3]== '3' or euler[i + 3]== '7' or euler[i + 3]== '9'):

changes to

euler[i + 2]== '1' or euler[i + 2]== '3' or euler[i + 2]== '7' or euler[i + 2]== '9'):

Similarly, think about what the range in the for loop should stretch to (i.e. len - 2 or len -3), even if it does not apply to this example.

In general, avoid using magic numbers at all. Define a variable or accept an input to set N = 3 or 10...

Also, you don't gain much by adding the if condition, only the potential for bugs (as above). Premature optimization is the root of all evil

For the second part, when you break your inner loop, you don't really establish any primality. You could do something simple like setting a flag. Here, I've modified your program to provide one example:

euler = '7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354'

for i in range(len(euler) - 2):
    if (euler[i + 2]== '1' or euler[i + 2]== '3' or euler[i + 2]== '7' or euler[i + 2]== '9'):
        number = int(euler[i:i + 3])
        for y in range(2, number-1):
            isPrime = True
            while y * y <= number:
                if (number % y != 0 or  number % (y+1) != 0):
                  isPrime = False # The number is not prime
                  break  # Exit loop

            if isPrime:  # Nothing was able to factorize the number
              print(number) # Print and leave
              exit(0)

However, your code is really quite broken and could do with a lot of attention and testing of the different edge cases.

Jedi
  • 3,088
  • 2
  • 28
  • 47
  • 1
    Thanks very much @Jedi. Definitely my code needs improvement, this is my 3rd week of a Python course I am taking online so thanks for your understanding! – Alan Jun 29 '17 at 19:42
0

For your first part, you are grasping the right-end non-inclusive property of range and slicing in Python. However, when you are just indexing to find an element, should you still care about that or not? By that I mean, is the third digit really indexed at i+3 for a number starting at position i?

For your second part, I am not quite seeing the mapping between your code and the pseudo-code.

Tips in general. You can compartmentalize the prime_check logic into a function that returns True or False, and call the function each time you get a number, then decide whether you want to print it and break or continue. Also, the comparisons you are doing for 1, 3, 7, 9 and be abbreviated with an in.

CaptainMeow
  • 351
  • 1
  • 6
  • Thanks @CaptainMeow for your helpful comment! – Alan Jun 29 '17 at 19:42
  • Yes that's true, the mapping between my code and the pseudo-code is not accurate. I had paste the wrong code. Thanks also for indicating the difference between the non-inclusive property of range that is absent when indexing. – Alan Jul 01 '17 at 00:07