#ProjectEuler/Python/Problem26.py #Matthew Ellison # Created: 07-29-19 #Modified: 07-19-20 #Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part. #Unless otherwise listed, all of my non-standard imports can be gotten from my pyClasses repository at https://bitbucket.org/Mattrixwv/pyClasses """ Copyright (C) 2020 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 Stopwatch import Stopwatch from Unsolved import Unsolved import Algorithms class Problem26(Problem): #Variables __topNumber = 999 #The largest denominator to be checked #Function #Constructor def __init__(self): super().__init__("Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.") self.longestCycle = 0 self.longestNumber = 0 #Operational function #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() #Start with 1/2 and find out how long the longest cycle is by checking the remainders #Loop through every number from 2-999 and use it for the denominator for denominator in range(2, self.__topNumber): remainderList = [] #Holds the list of remainders endFound = False #Holds whether we have found an end to the number (either a cycle or a 0 for remainder) cycleFound = False #Holds whether a cycle was detected numerator = 1 #The numerator that will be divided while(not endFound): #Get the remainder after the division remainder = numerator % denominator #Check if the remainder is 0 #If it is set the flag if(remainder == 0): endFound = True #Check if the remainder is in the list #If it is in the list, set the appropriate flags elif remainder in remainderList: endFound = True cycleFound = True #Else add it to the list else: remainderList.append(remainder) #Multiply the remainder by 10 to continue finding the next remainder numerator = remainder * 10 #If a cycle was found check the size of the list against the largest cycle if(cycleFound): #If it is larger than the largest, set it as the new largest if(len(remainderList) > self.longestCycle): self.longestCycle = len(remainderList) self.longestNumber = denominator #Stop the timer self.timer.stop() #Print the results self.result = "The longest cycle is " + str(self.longestCycle) + " digits long" + "\nIt is started with the number " + str(self.longestNumber) #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.longestCycle = 0 self.longestNumber = 0 #Gets #Returns the length of the longest cycle def getLongestCycle(self) -> int: #If the problem hasn't been solved throw an exception if(not self.solved): raise Unsolved("You must solve the problem before can you see the length of the longest cycle") return self.longestCycle #Returns the denominator that starts the longest cycle def getLongestNumber(self) -> int: #If the problem hasn't been solved throw an exception if(not self.solved): raise Unsolved("You must solve the problem before can you see the denominaotr that started the cycle") return self.longestNumber #This calls the appropriate functions if the script is called stand along if __name__ == "__main__": problem = Problem26() print(problem.getDescription()) #Print the description problem.solve() #Call the function that answers the problem #Print the results print(problem.getResult()) print("It took " + problem.getTime() + " to solve this algorithm") """ Results: The longest cycle is 982 digits long It is started with the number 983 It took 182.704 milliseconds to run this algorithm """