diff --git a/ProblemSelection.py b/ProblemSelection.py index d0c4499..20c228f 100644 --- a/ProblemSelection.py +++ b/ProblemSelection.py @@ -58,6 +58,7 @@ from Problems.Problem33 import Problem33 from Problems.Problem34 import Problem34 from Problems.Problem35 import Problem35 from Problems.Problem36 import Problem36 +from Problems.Problem37 import Problem37 from Problems.Problem67 import Problem67 @@ -66,7 +67,7 @@ class ProblemSelection: problemNumbers = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 67] + 31, 32, 33, 34, 35, 36, 37, 67] #Returns the problem corresponding to the given problem number @staticmethod @@ -143,6 +144,8 @@ class ProblemSelection: return Problem35() elif(problemNumber == 36): return Problem36() + elif(problemNumber == 37): + return Problem37() elif(problemNumber == 67): return Problem67() diff --git a/Problems/Problem37.py b/Problems/Problem37.py new file mode 100644 index 0000000..425f3c7 --- /dev/null +++ b/Problems/Problem37.py @@ -0,0 +1,137 @@ +#ProjectEuler/ProjectEulerPython/Problems/Problem37.py +#Matthew Ellison +# Created: 07-01-21 +#Modified: 07-01-21 +#Find the sum of the only eleven primes that are both truncatable from left to right and right to left (2, 3, 5, and 7 are not counted). +#Unless otherwise listed, all of my non-standard imports can be gotten from my pyClasses repository at https://bitbucket.org/Mattrixwv/pyClasses +""" + Copyright (C) 2021 Matthew Ellison + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +""" + + +from Problems.Problem import Problem +from Unsolved import Unsolved + +import Algorithms + + +class Problem37(Problem): + #Variables + __last_prime_before_check = 7 #The last prime before 11 since single digit primes aren't checked + + #Functions + #Constructor + def __init__(self): + super().__init__("Find the sum of the only eleven primes that are both truncatable from left to right and right to left (2, 3, 5, and 7 are not counted).") + self.truncPrimes = [] #All numbers that are truncatable primes + self.sumOfTruncPrimes = 0 #The sum of all elements in truncPrimes + + #Operational functions + #Solve the problem + def solve(self): + #If the problem has already been solved do nothing and end the function + if(self.solved): + return + + #Start the timer + self.timer.start() + + #Create the sieve and get the first prime number + sieve = Algorithms.primeGenerator() + currentPrime = next(sieve) + #Loop through the sieve until you get to __last_prime_before_check + while(currentPrime < self.__last_prime_before_check): + currentPrime = next(sieve) + #Loop until truncPrimes contains 11 elements + while(len(self.truncPrimes) < 11): + isTruncPrime = True + #Get the next prime + currentPrime = next(sieve) + #Convert the prime to a string + primeString = str(currentPrime) + #If the string contains an even digit move to the next prime + for strLoc in range(0, len(primeString)): + #Allow 2 to be the first digit + if((strLoc == 0) and (primeString[strLoc] == '2')): + continue + if((primeString[strLoc] == '0') or (primeString[strLoc] == '2') or (primeString[strLoc] == '4') or (primeString[strLoc] == '6') or (primeString[strLoc] == '8')): + isTruncPrime = False + break + #Start removing digits from the left and see if the number stays prime + if(isTruncPrime): + for truncLoc in range(1, len(primeString)): + #Create a substring of the prime, removing the needed digits from the left + primeSubstring = primeString[truncLoc::] + #Convert the string to an int and see if the number is still prime + newPrime = int(primeSubstring) + if(not Algorithms.isPrime(newPrime)): + isTruncPrime = False + break + #Start removing digits from the right and see if the number stays prime + if(isTruncPrime): + for truncLoc in range(1, len(primeString)): + #Create a substring of the prime, removing the needed digits from the right + primeSubstring = primeString[0:len(primeString) - truncLoc] + #Convert the string to an int and see if the number is still prime + newPrime = int(primeSubstring) + if(not Algorithms.isPrime(newPrime)): + isTruncPrime = False + break + #If the number remained prime through all operations add it to the vector + if(isTruncPrime): + self.truncPrimes.append(currentPrime) + #End the loop if we have collected enough primes + if(len(self.truncPrimes) == 11): + break + #Get the sum of all elements in the truncPrimes vector + self.sumOfTruncPrimes = sum(self.truncPrimes) + + #Stop the timer + self.timer.stop() + + #Throw a flag to show the problem is solved + self.solved = True + + #Reset the problem so it can be run again + def reset(self): + super().reset() + self.truncPrimes = [] + self.sumOfTruncPrimes = 0 + + #Gets + #Returns a string with the solution to the problem + def getResult(self) -> str: + #If the problem hasn't been solved throw an exception + if(not self.solved): + raise Unsolved("You must solve the porblem before you can see the result") + return f"The sum of all left and right truncatable primes is {self.sumOfTruncPrimes}" + #Returns the list of primes that can be truncated + def getTruncatablePrimes(self) -> list: + #If the problem hasn't been solved throw an exception + if(not self.solved): + raise Unsolved("You must solve the porblem before you can see the truncatable primes") + return self.truncPrimes + #Returns the sum of all elements in truncPrimes + def getSumOfPrimes(self) -> int: + #If the problem hasn't been solved throw an exception + if(not self.solved): + raise Unsolved("You must solve the porblem before you can see the sum of the truncatable primes") + return self.sumOfTruncPrimes + +""" Results: +The sum of all left and right truncatable primes is 748317 +It took an average of 224.657 milliseconds to run this problem through 100 iterations +"""