Search code examples
pythoneulers-number

Google Puzzle Euler Number


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?


Solution

  • 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.