diff --git a/Python/p041.py b/Python/p041.py index d15cb6b..cc3075f 100644 --- a/Python/p041.py +++ b/Python/p041.py @@ -5,34 +5,27 @@ # # What is the largest n-digit pandigital prime that exists? -from timeit import default_timer - -from projecteuler import is_pandigital, is_prime +from projecteuler import is_pandigital, is_prime, timing -def main(): - start = default_timer() - -# 8- and 9-digit pandigital numbers can't be prime, because -# 1+2+...+8=36, which is divisible by 3, and 36+9=45 which is -# also divisible by 3, and therefore the whole number is divisible -# by 3. So we can start from the largest 7-digit pandigital number, -# until we find a prime. +@timing +def p041(): + # 8- and 9-digit pandigital numbers can't be prime, because + # 1+2+...+8=36, which is divisible by 3, and 36+9=45 which is + # also divisible by 3, and therefore the whole number is divisible + # by 3. So we can start from the largest 7-digit pandigital number, + # until we find a prime. i = 7654321 while i > 0: if is_pandigital(i, len(str(i))) and is_prime(i): break -# Skipping the even numbers. + # Skipping the even numbers. i = i - 2 - end = default_timer() - print('Project Euler, Problem 41') print(f'Answer: {i}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p041() diff --git a/Python/p042.py b/Python/p042.py index 9010457..1b1151e 100644 --- a/Python/p042.py +++ b/Python/p042.py @@ -11,7 +11,8 @@ # how many are triangle words? import sys -from timeit import default_timer + +from projecteuler import timing def is_triang(n): @@ -27,9 +28,8 @@ def is_triang(n): return False -def main(): - start = default_timer() - +@timing +def p042(): try: with open('p042_words.txt', 'r', encoding='utf-8') as fp: words = list(fp.readline().replace('"', '').split(',')) @@ -39,7 +39,7 @@ def main(): count = 0 -# For each word, calculate its value and check if it's a triangle number. + # For each word, calculate its value and check if it's a triangle number. for word in words: value = 0 l = len(word) @@ -50,13 +50,9 @@ def main(): if is_triang(value): count = count + 1 - end = default_timer() - print('Project Euler, Problem 42') print(f'Answer: {count}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p042() diff --git a/Python/p043.py b/Python/p043.py index f7621f0..84ba91e 100644 --- a/Python/p043.py +++ b/Python/p043.py @@ -16,7 +16,8 @@ # Find the sum of all 0 to 9 pandigital numbers with this property. from itertools import permutations -from timeit import default_timer + +from projecteuler import timing # Function to check if the value has the desired property. @@ -59,26 +60,21 @@ def has_property(n): return True -def main(): - start = default_timer() - -# Find all the permutations +@timing +def p043(): + # Find all the permutations perm = list(permutations('0123456789')) sum_ = 0 -# For each permutation, check if it has the required property + # For each permutation, check if it has the required property for i in perm: if has_property(i): sum_ = sum_ + int(''.join(map(str, i))) - end = default_timer() - print('Project Euler, Problem 43') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p043() diff --git a/Python/p044.py b/Python/p044.py index b348d9c..7949196 100644 --- a/Python/p044.py +++ b/Python/p044.py @@ -9,20 +9,17 @@ # Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference are pentagonal and D = |Pk − Pj| is minimised; # what is the value of D? -from timeit import default_timer - -from projecteuler import is_pentagonal +from projecteuler import is_pentagonal, timing -def main(): - start = default_timer() - +@timing +def p044(): found = 0 n = 2 -# Check all couples of pentagonal numbers until the right one -# is found. Use the function implemented in projecteuler.py to -# check if the sum and difference ot the two numbers is pentagonal. + # Check all couples of pentagonal numbers until the right one + # is found. Use the function implemented in projecteuler.py to + # check if the sum and difference ot the two numbers is pentagonal. while not found: pn = n * (3 * n - 1) // 2 @@ -35,13 +32,9 @@ def main(): n = n + 1 - end = default_timer() - print('Project Euler, Problem 44') print(f'Answer: {pn - pm}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p044() diff --git a/Python/p045.py b/Python/p045.py index cad8098..867cef6 100644 --- a/Python/p045.py +++ b/Python/p045.py @@ -10,34 +10,27 @@ # # Find the next triangle number that is also pentagonal and hexagonal. -from timeit import default_timer - -from projecteuler import is_pentagonal +from projecteuler import is_pentagonal, timing -def main(): - start = default_timer() - +@timing +def p045(): found = 0 i = 143 while not found: i = i + 1 -# Hexagonal numbers are also triangle numbers, so it's sufficient -# to generate hexagonal numbers (starting from H_144) and check if -# they're also pentagonal. + # Hexagonal numbers are also triangle numbers, so it's sufficient + # to generate hexagonal numbers (starting from H_144) and check if + # they're also pentagonal. n = i * (2 * i - 1) if is_pentagonal(n): found = 1 - end = default_timer() - print('Project Euler, Problem 45') print(f'Answer: {n}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p045() diff --git a/Python/p046.py b/Python/p046.py index ab391b2..b959951 100644 --- a/Python/p046.py +++ b/Python/p046.py @@ -13,9 +13,7 @@ # # What is the smallest odd composite that cannot be written as the sum of a prime and twice a square? -from timeit import default_timer - -from projecteuler import sieve +from projecteuler import sieve, timing N = 10000 @@ -23,13 +21,13 @@ primes = sieve(N) def goldbach(n): -# Check every prime smaller than n. + # Check every prime smaller than n. for i in range(3, n, 2): if primes[i] == 1: j = 1 -# Check if summing twice a square to the prime number -# gives n. Return 1 when succeeding. + # Check if summing twice a square to the prime number + # gives n. Return 1 when succeeding. while True: tmp = i + 2 * j * j @@ -41,31 +39,27 @@ def goldbach(n): if tmp >= n: break -# Return 0 if no solution is found. + # Return 0 if no solution is found. return False -def main(): - start = default_timer() +@timing +def p046(): found = 0 i = 3 -# For every odd number, check if it's prime, if it is check -# if it satisfies the Goldbach property. Continue until the -# first number that doesn't is found. + # For every odd number, check if it's prime, if it is check + # if it satisfies the Goldbach property. Continue until the + # first number that doesn't is found. while not found and i < N: if primes[i] == 0: if not goldbach(i): found = 1 i = i + 2 - end = default_timer() - print('Project Euler, Problem 46') print(f'Answer: {i - 2}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p046() diff --git a/Python/p047.py b/Python/p047.py index ca072dd..c9ff23a 100644 --- a/Python/p047.py +++ b/Python/p047.py @@ -13,7 +13,7 @@ # # Find the first four consecutive integers to have four distinct prime factors each. What is the first of these numbers? -from timeit import default_timer +from projecteuler import timing # Function using a modified sieve of Eratosthenes to count @@ -31,17 +31,16 @@ def count_factors(n): return factors -def main(): - start = default_timer() - +@timing +def p047(): N = 150000 factors = count_factors(N) count = 0 -# Find the first instance of four consecutive numbers -# having four distinct prime factors. + # Find the first instance of four consecutive numbers + # having four distinct prime factors. for i in range(N): if factors[i] == 4: count = count + 1 @@ -52,13 +51,9 @@ def main(): res = i - 3 break - end = default_timer() - print('Project Euler, Problem 47') print(f'Answer: {res}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p047() diff --git a/Python/p048.py b/Python/p048.py index 2fdf0a5..d93ba3d 100644 --- a/Python/p048.py +++ b/Python/p048.py @@ -4,26 +4,21 @@ # # Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000. -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p048(): sum_ = 0 -# Simply calculate the sum of the powers + # Simply calculate the sum of the powers for i in range(1, 1001): power = i ** i sum_ = sum_ + power - end = default_timer() - print('Project Euler, Problem 48') print(f'Answer: {str(sum_)[-10:]}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p048() diff --git a/Python/p049.py b/Python/p049.py index cf5d76e..c79e939 100644 --- a/Python/p049.py +++ b/Python/p049.py @@ -8,14 +8,11 @@ # # What 12-digit number do you form by concatenating the three terms in this sequence? -from timeit import default_timer - -from projecteuler import sieve +from projecteuler import sieve, timing -def main(): - start = default_timer() - +@timing +def p049(): N = 10000 primes = sieve(N) @@ -23,15 +20,14 @@ def main(): found = 0 i = 1489 -# Starting from i=1489 (bigger than the first number in the sequence given in the problem), -# check odd numbers. If they're prime, loop on even numbers j (odd+even=odd, odd+odd=even and -# we need odd numbers because we're looking for primes) up to 4254 (1489+2*4256=10001 which has -# 5 digits. + # Starting from i=1489 (bigger than the first number in the sequence given in the problem), + # check odd numbers. If they're prime, loop on even numbers j (odd+even=odd, odd+odd=even and + # we need odd numbers because we're looking for primes) up to 4254 (1489+2*4256=10001 which has + # 5 digits. while i < N: if primes[i] == 1: for j in range(1, 4255): -# If i, i+j and i+2*j are all primes and they have -# all the same digits, the result has been found. + # If i, i+j and i+2*j are all primes and they have all the same digits, the result has been found. if i + 2 * j < N and primes[i+j] == 1 and primes[i+2*j] == 1 and\ ''.join(sorted(str(i))) == ''.join(sorted(str(i+j))) and\ ''.join(sorted(str(i))) == ''.join(sorted(str(i+2*j))): @@ -42,13 +38,9 @@ def main(): i = i + 2 - end = default_timer() - print('Project Euler, Problem 49') print(f'Answer: {str(i)+str(i+j)+str(i+2*j)}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p049() diff --git a/Python/p050.py b/Python/p050.py index ba17739..c4c765f 100644 --- a/Python/p050.py +++ b/Python/p050.py @@ -10,14 +10,11 @@ # # Which prime, below one-million, can be written as the sum of the most consecutive primes? -from timeit import default_timer - -from projecteuler import sieve +from projecteuler import sieve, timing -def main(): - start = default_timer() - +@timing +def p050(): N = 1000000 primes = sieve(N) @@ -25,12 +22,12 @@ def main(): max_ = 0 max_p = 0 -# Starting from a prime i, add consecutive primes until the -# sum exceeds the limit, every time the sum is also a prime -# save the value and the count if the count is larger than the -# current maximum. Repeat for all primes below N. -# A separate loop is used for i=2, so later only odd numbers are -# checked for primality. + # Starting from a prime i, add consecutive primes until the + # sum exceeds the limit, every time the sum is also a prime + # save the value and the count if the count is larger than the + # current maximum. Repeat for all primes below N. + # A separate loop is used for i=2, so later only odd numbers are + # checked for primality. i = 2 j = i + 1 count = 1 @@ -63,13 +60,9 @@ def main(): j = j + 2 - end = default_timer() - print('Project Euler, Problem 50') print(f'Answer: {max_p}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p050() diff --git a/Python/p051.py b/Python/p051.py index 1c5132f..361b251 100644 --- a/Python/p051.py +++ b/Python/p051.py @@ -9,13 +9,10 @@ # Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime # value family. -from timeit import default_timer - -from projecteuler import sieve +from projecteuler import sieve, timing N = 1000000 - # N set to 1000000 as a reasonable limit, which turns out to be enough. primes = sieve(N) @@ -38,8 +35,8 @@ def replace(n): for i in range(l-3): for j in range(i+1, l-2): -# Replacing the last digit can't give 8 primes, because at least -# six of the numbers obtained will be divisible by 2 and/or 5. + # Replacing the last digit can't give 8 primes, because at least + # six of the numbers obtained will be divisible by 2 and/or 5. for k in range(j+1, l-1): count = 0 @@ -64,32 +61,28 @@ def replace(n): return max_ -def main(): - start = default_timer() -# Checking only odd numbers with at least 4 digits. +@timing +def p051(): + # Checking only odd numbers with at least 4 digits. i = 1001 while i < N: -# The family of numbers needs to have at least one of 0, 1 or 2 as -# repeated digits, otherwise we can't get a 8 number family (there -# are only 7 other digits). Also, te number of repeated digits must -# be 3, otherwise at least 3 resulting numbers will be divisible by 3. -# So the smallest number of this family must have three 0s, three 1s or -# three 2s. + # The family of numbers needs to have at least one of 0, 1 or 2 as + # repeated digits, otherwise we can't get a 8 number family (there + # are only 7 other digits). Also, te number of repeated digits must + # be 3, otherwise at least 3 resulting numbers will be divisible by 3. + # So the smallest number of this family must have three 0s, three 1s or + # three 2s. if count_digit(i, 0) >= 3 or count_digit(i, 1) >= 3 or\ count_digit(i, 2) >= 3: if primes[i] == 1 and replace(i) == 8: break i = i + 2 - end = default_timer() - print('Project Euler, Problem 51') print(f'Answer: {i}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p051() diff --git a/Python/p052.py b/Python/p052.py index 27a338e..5db0958 100644 --- a/Python/p052.py +++ b/Python/p052.py @@ -4,15 +4,14 @@ # # Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits. -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p052(): i = 1 -# Brute force approach, try every integer number until the desired one is found. + # Brute force approach, try every integer number until the desired one is found. while True: if ''.join(sorted(str(i))) == ''.join(sorted(str(2*i))) and\ ''.join(sorted(str(i))) == ''.join(sorted(str(3*i))) and\ @@ -22,13 +21,9 @@ def main(): break i = i + 1 - end = default_timer() - print('Project Euler, Problem 52') print(f'Answer: {i}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p052() diff --git a/Python/p053.py b/Python/p053.py index 25bd95a..1cb1342 100644 --- a/Python/p053.py +++ b/Python/p053.py @@ -12,31 +12,26 @@ # # How many, not necessarily distinct, values of (n r) for 1≤n≤100, are greater than one-million? -from timeit import default_timer - from scipy.special import comb +from projecteuler import timing -def main(): - start = default_timer() +@timing +def p053(): LIMIT = 1000000 count = 0 -# Use the scipy comb function to calculate the binomial values + # Use the scipy comb function to calculate the binomial values for i in range(23, 101): for j in range(1, i+1): if comb(i, j) > LIMIT: count = count + 1 - end = default_timer() - print('Project Euler, Problem 53') print(f'Answer: {count}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p053() diff --git a/Python/p054.py b/Python/p054.py index bd00b3a..7477a5e 100644 --- a/Python/p054.py +++ b/Python/p054.py @@ -48,7 +48,8 @@ import sys from enum import IntEnum -from timeit import default_timer + +from projecteuler import timing class Value(IntEnum): @@ -111,7 +112,7 @@ class Hand(): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.cards = list() + self.cards = [] def sort(self): self.cards.sort(key=lambda x: x.value) @@ -126,8 +127,7 @@ class Game(): self.hand2 = None def play(self): - -# If player 1 has a Royal Flush, player 1 wins. + # If player 1 has a Royal Flush, player 1 wins. if self.hand1.cards[4].value == Value.Ace and self.hand1.cards[3].value == Value.King and\ self.hand1.cards[2].value == Value.Queen and self.hand1.cards[1].value == Value.Jack and\ self.hand1.cards[0] == Value.Ten and self.hand1.cards[0].suit == self.hand1.cards[1].suit and\ @@ -136,7 +136,7 @@ class Game(): self.hand1.cards[0].suit == self.hand1.cards[4].suit: return 1 -# If player 2 has a Royal Flush, player 2 wins. + # If player 2 has a Royal Flush, player 2 wins. if self.hand2.cards[4].value == Value.Ace and self.hand2.cards[3].value == Value.King and\ self.hand2.cards[2].value == Value.Queen and self.hand2.cards[1].value == Value.Jack and\ self.hand2.cards[0] == Value.Ten and self.hand2.cards[0].suit == self.hand2.cards[1].suit and\ @@ -148,7 +148,7 @@ class Game(): straightflush1 = 0 straightflush2 = 0 -# Check if player 1 has a straight flush. + # Check if player 1 has a straight flush. if self.hand1.cards[0].suit == self.hand1.cards[1].suit and self.hand1.cards[0].suit == self.hand1.cards[2].suit and\ self.hand1.cards[0].suit == self.hand1.cards[3].suit and self.hand1.cards[0].suit == self.hand1.cards[4].suit: value = self.hand1.cards[0].value @@ -162,7 +162,7 @@ class Game(): straightflush1 = 0 break -# Check if player 2 has a straight flush. + # Check if player 2 has a straight flush. if self.hand2.cards[0].suit == self.hand2.cards[1].suit and self.hand2.cards[0].suit == self.hand2.cards[2].suit and\ self.hand2.cards[0].suit == self.hand2.cards[3].suit and self.hand2.cards[0].suit == self.hand2.cards[4].suit: value = self.hand2.cards[0].value @@ -176,17 +176,17 @@ class Game(): straightflush2 = 0 break -# If player 1 has a straight flush and player 2 doesn't, player 1 wins + # If player 1 has a straight flush and player 2 doesn't, player 1 wins if straightflush1 and not straightflush2: return 1 -# If player 2 has a straight flush and player 1 doesn't, player 2 wins + # If player 2 has a straight flush and player 1 doesn't, player 2 wins if not straightflush1 and straightflush2: return -1 -# If both players have a straight flush, the one with the highest value wins. -# Any card can be compared, because in the straight flush the values are consecutive -# by definition. + # If both players have a straight flush, the one with the highest value wins. + # Any card can be compared, because in the straight flush the values are consecutive + # by definition. if straightflush1 and straightflush2: if self.hand1.cards[0].value > self.hand2.cards[0].value: return 1 @@ -196,24 +196,24 @@ class Game(): four1 = 0 four2 = 0 -# Check if player 1 has four of a kind. Since cards are ordered, it is sufficient -# to check if the first card is equal to the fourth or if the second is equal to the fifth. + # Check if player 1 has four of a kind. Since cards are ordered, it is sufficient + # to check if the first card is equal to the fourth or if the second is equal to the fifth. if self.hand1.cards[0].value == self.hand1.cards[3].value or self.hand1.cards[1].value == self.hand1.cards[4].value: four1 = 1 -# Check if player 2 has four of a kind + # Check if player 2 has four of a kind if self.hand2.cards[0].value == self.hand2.cards[3].value or self.hand2.cards[1].value == self.hand2.cards[4].value: four2 = 1 -# If player 1 has four of a kind and player 2 doesn't, player 1 wins. + # If player 1 has four of a kind and player 2 doesn't, player 1 wins. if four1 and not four2: return 1 -# If player 2 has four of a kind and player 1 doesn't, player 2 wins. + # If player 2 has four of a kind and player 1 doesn't, player 2 wins. if not four1 and four2: return -1 -# If both players have four of a kind, check who has the highest value for those four cards. + # If both players have four of a kind, check who has the highest value for those four cards. if four1 and four2: if self.hand1.cards[1].value > self.hand2.cards[1].value: return 1 @@ -223,27 +223,26 @@ class Game(): full1 = 0 full2 = 0 -# Check if player 1 has a full house. + # Check if player 1 has a full house. if self.hand1.cards[0].value == self.hand1.cards[1].value and self.hand1.cards[3].value == self.hand1.cards[4].value and\ (self.hand1.cards[1].value == self.hand1.cards[2].value or self.hand1.cards[2].value == self.hand1.cards[3].value): full1 = 1 -# Check if player 2 has a full house. + # Check if player 2 has a full house. if self.hand2.cards[0].value == self.hand2.cards[1].value and self.hand2.cards[3].value == self.hand2.cards[4].value and\ (self.hand2.cards[1].value == self.hand2.cards[2].value or self.hand2.cards[2].value == self.hand2.cards[3].value): full2 = 1 -# If player 1 has a full house and player 2 doesn't, player 1 wins. + # If player 1 has a full house and player 2 doesn't, player 1 wins. if full1 and not full2: return 1 -# If player 2 has a full house and player 1 doesn't, player 2 wins. + # If player 2 has a full house and player 1 doesn't, player 2 wins. if not full1 and full2: return -1 -# If both players have a full house, check who has the highest value -# for the three equal cards (the third card in the array will be part -# of the set of three). + # If both players have a full house, check who has the highest value for the three equal cards (the third card in the array will be part + # of the set of three). if full1 and full2: if self.hand1.cards[2].value > self.hand2.cards[2].value: return 1 @@ -254,28 +253,28 @@ class Game(): flush1 = 0 flush2 = 0 -# Check if player 1 has a flush. + # Check if player 1 has a flush. if self.hand1.cards[0].suit == self.hand1.cards[1].suit and self.hand1.cards[0].suit == self.hand1.cards[2].suit and\ self.hand1.cards[0].suit == self.hand1.cards[3].suit and self.hand1.cards[0].suit == self.hand1.cards[4].suit: flush1 = 1 -# Check if player 2 has a flush. + # Check if player 2 has a flush. if self.hand2.cards[0].suit == self.hand2.cards[1].suit and self.hand2.cards[0].suit == self.hand2.cards[2].suit and\ self.hand2.cards[0].suit == self.hand2.cards[3].suit and self.hand2.cards[0].suit == self.hand2.cards[4].suit: flush2 = 1 -# If player 1 has a flush and player 2 doesn't, player 1 wins. + # If player 1 has a flush and player 2 doesn't, player 1 wins. if flush1 and not flush2: return 1 -# If player 2 has a flush and player 1 doesn't, player 2 wins. + # If player 2 has a flush and player 1 doesn't, player 2 wins. if not flush1 and flush2: return -1 straight1 = 1 straight2 = 1 -# Check if player 1 has a straight. + # Check if player 1 has a straight. value = self.hand1.cards[0].value for i in range(1, 5): @@ -285,7 +284,7 @@ class Game(): straight1 = 0 break -# Check if player 2 has a straight. + # Check if player 2 has a straight. value = self.hand2.cards[0].value for i in range(1, 5): @@ -295,34 +294,34 @@ class Game(): straight2 = 0 break -# If player 1 has a straight and player 2 doesn't, player 1 wins. + # If player 1 has a straight and player 2 doesn't, player 1 wins. if straight1 and not straight2: return 1 -# If player 2 has a straight and player 1 doesn't, player 2 wins. + # If player 2 has a straight and player 1 doesn't, player 2 wins. if not straight1 and straight2: return -1 three1 = 0 three2 = 0 -# Check if player 1 has three of a kind. + # Check if player 1 has three of a kind. if (self.hand1.cards[0].value == self.hand1.cards[1].value and self.hand1.cards[0].value == self.hand1.cards[2].value) or\ (self.hand1.cards[1].value == self.hand1.cards[2].value and self.hand1.cards[1].value == self.hand1.cards[3].value) or\ (self.hand1.cards[2].value == self.hand1.cards[3].value and self.hand1.cards[2].value == self.hand1.cards[4].value): three1 = 1 -# Check if player 2 has three of a kind. + # Check if player 2 has three of a kind. if (self.hand2.cards[0].value == self.hand2.cards[1].value and self.hand2.cards[0].value == self.hand2.cards[2].value) or\ (self.hand2.cards[1].value == self.hand2.cards[2].value and self.hand2.cards[1].value == self.hand2.cards[3].value) or\ (self.hand2.cards[2].value == self.hand2.cards[3].value and self.hand2.cards[2].value == self.hand2.cards[4].value): three2 = 1 -# If player 1 has three of a kind and player 2 doesn't, player 1 wins. + # If player 1 has three of a kind and player 2 doesn't, player 1 wins. if three1 and not three2: return 1 -# If player 2 has three of a kind and player 1 doesn't, player 2 wins. + # If player 2 has three of a kind and player 1 doesn't, player 2 wins. if not three1 and three2: return -1 @@ -336,28 +335,28 @@ class Game(): twopairs1 = 0 twopairs2 = 0 -# Check if player 1 has two pairs. + # Check if player 1 has two pairs. if (self.hand1.cards[0].value == self.hand1.cards[1].value and self.hand1.cards[2].value == self.hand1.cards[3].value) or\ (self.hand1.cards[0].value == self.hand1.cards[1].value and self.hand1.cards[3].value == self.hand1.cards[4].value) or\ (self.hand1.cards[1].value == self.hand1.cards[2].value and self.hand1.cards[3].value == self.hand1.cards[4].value): twopairs1 = 1 -# Check if player 2 has two pairs. + # Check if player 2 has two pairs. if (self.hand2.cards[0].value == self.hand2.cards[1].value and self.hand2.cards[2].value == self.hand2.cards[3].value) or\ (self.hand2.cards[0].value == self.hand2.cards[1].value and self.hand2.cards[3].value == self.hand2.cards[4].value) or\ (self.hand2.cards[1].value == self.hand2.cards[2].value and self.hand2.cards[3].value == self.hand2.cards[4].value): twopairs2 = 1 -# If player 1 has two pairs and player 2 doesn't, player 1 wins. + # If player 1 has two pairs and player 2 doesn't, player 1 wins. if twopairs1 and not twopairs2: return 1 -# If player 2 has two pairs and player 1 doesn't, player 2 wins. + # If player 2 has two pairs and player 1 doesn't, player 2 wins. if not twopairs1 and twopairs2: return -1 -# If both players have two pairs, check who has the highest pair. If it's equal, -# check the other pair. If it's still equal, check the remaining card. + # If both players have two pairs, check who has the highest pair. If it's equal, + # check the other pair. If it's still equal, check the remaining card. if twopairs1 and twopairs2: if self.hand1.cards[3].value > self.hand2.cards[3].value: return 1 @@ -381,28 +380,28 @@ class Game(): pair1 = 0 pair2 = 0 -# Check if player 1 has a pair of cards. + # Check if player 1 has a pair of cards. if self.hand1.cards[0].value == self.hand1.cards[1].value or self.hand1.cards[1].value == self.hand1.cards[2].value or\ self.hand1.cards[2].value == self.hand1.cards[3].value or self.hand1.cards[3].value == self.hand1.cards[4].value: pair1 = 1 -# Check if player 2 has a pair of cards. + # Check if player 2 has a pair of cards. if self.hand2.cards[0].value == self.hand2.cards[1].value or self.hand2.cards[1].value == self.hand2.cards[2].value or\ self.hand2.cards[2].value == self.hand2.cards[3].value or self.hand2.cards[3].value == self.hand2.cards[4].value: pair2 = 1 -# If player 1 has a pair of cards and player 2 doesn't, player 1 wins. + # If player 1 has a pair of cards and player 2 doesn't, player 1 wins. if pair1 and not pair2: return 1 -# If player 2 has a pair of cards and player 1 doesn't, player 2 wins. + # If player 2 has a pair of cards and player 1 doesn't, player 2 wins. if not pair1 and pair2: return -1 -# If both players have a pair of cards, check who has the highest pair. Since cards are -# ordered by value, either card[1] will be part of the pair (card[0]=card[1] or -# card[1]=card[2]) or card[3] will be part of the pair (card[2]=card[3] or -# card[3]=card[4]). + # If both players have a pair of cards, check who has the highest pair. Since cards are + # ordered by value, either card[1] will be part of the pair (card[0]=card[1] or + # card[1]=card[2]) or card[3] will be part of the pair (card[2]=card[3] or + # card[3]=card[4]). if pair1 and pair2: if self.hand1.cards[0].value == self.hand1.cards[1].value or self.hand1.cards[1].value == self.hand1.cards[2].value: value = self.hand1.cards[1].value @@ -432,20 +431,19 @@ class Game(): if value < self.hand2.cards[3].value: return -1 -# If all other things are equal, check who has the highest card, if it's equal check the second highest and so on. + # If all other things are equal, check who has the highest card, if it's equal check the second highest and so on. for i in range(4, -1, -1): if self.hand1.cards[i].value > self.hand2.cards[i].value: return 1 if self.hand1.cards[i].value < self.hand2.cards[i].value: return -1 -# If everything is equal, return 0 + # If everything is equal, return 0 return 0 -def main(): - start = default_timer() - +@timing +def p054(): try: with open('p054_poker.txt', 'r', encoding='utf-8') as fp: games = fp.readlines() @@ -476,7 +474,7 @@ def main(): hand1.sort() hand2.sort() - for k in hand1.cards: + for _ in hand1.cards: game = Game() game.hand1 = hand1 game.hand2 = hand2 @@ -484,13 +482,9 @@ def main(): if game.play() == 1: count = count + 1 - end = default_timer() - print('Project Euler, Problem 54') print(f'Answer: {count}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p054() diff --git a/Python/p055.py b/Python/p055.py index 52a0602..773af9a 100644 --- a/Python/p055.py +++ b/Python/p055.py @@ -23,28 +23,26 @@ # # NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers. -from timeit import default_timer - -from projecteuler import is_palindrome +from projecteuler import is_palindrome, timing def is_lychrel(n): tmp = n -# Run for 50 iterations + # Run for 50 iterations for _ in range(50): reverse = 0 -# Find the reverse of the given number + # Find the reverse of the given number while tmp > 0: reverse = reverse * 10 reverse = reverse + tmp % 10 tmp = tmp // 10 -# Add the reverse to the original number + # Add the reverse to the original number tmp = n + reverse -# If the sum is palindrome, the number is not a Lychrel number. + # If the sum is palindrome, the number is not a Lychrel number. if is_palindrome(tmp, 10): return False @@ -53,24 +51,19 @@ def is_lychrel(n): return True -def main(): - start = default_timer() - +@timing +def p055(): count = 0 -# For each number, use the is_lychrel function to check if the number -# is a Lychrel number. + # For each number, use the is_lychrel function to check if the number + # is a Lychrel number. for i in range(1, 10000): if is_lychrel(i): count = count + 1 - end = default_timer() - print('Project Euler, Problem 55') print(f'Answer: {count}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p055() diff --git a/Python/p056.py b/Python/p056.py index 2252c32..706b4f7 100644 --- a/Python/p056.py +++ b/Python/p056.py @@ -5,15 +5,14 @@ # # Considering natural numbers of the form, a^b, where a, b < 100, what is the maximum digital sum? -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p056(): max_ = 0 -# Straightforward brute force approach + # Straightforward brute force approach for a in range(1, 100): for b in range(1, 100): p = a ** b @@ -26,13 +25,9 @@ def main(): if sum_ > max_: max_ = sum_ - end = default_timer() - print('Project Euler, Problem 56') print(f'Answer: {max_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p056() diff --git a/Python/p057.py b/Python/p057.py index 5297bda..2338860 100644 --- a/Python/p057.py +++ b/Python/p057.py @@ -16,18 +16,17 @@ # # In the first one-thousand expansions, how many fractions contain a numerator with more digits than the denominator? -from timeit import default_timer +from projecteuler import timing -def main(): - start = default_timer() - +@timing +def p057(): n = 1 d = 1 count = 0 -# If n/d is the current term of the expansion, the next term can be calculated as -# (n+2d)/(n+d). + # If n/d is the current term of the expansion, the next term can be calculated as + # (n+2d)/(n+d). for _ in range(1, 1000): d2 = 2 * d d = n + d @@ -36,13 +35,9 @@ def main(): if len(str(n)) > len(str(d)): count = count + 1 - end = default_timer() - print('Project Euler, Problem 57') print(f'Answer: {count}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p057() diff --git a/Python/p058.py b/Python/p058.py index fbfbfba..2d6b6c7 100644 --- a/Python/p058.py +++ b/Python/p058.py @@ -16,19 +16,16 @@ # If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, # what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%? -from timeit import default_timer - -from projecteuler import is_prime +from projecteuler import is_prime, timing -def main(): - start = default_timer() - -# Starting with 1, the next four numbers in the diagonal are 3 (1+2), 5 (1+2+2), 7 (1+2+2+2) -# and 9 (1+2+2+2+2). Check which are prime, increment the counter every time a new prime is -# found, and divide by the number of elements of the diagonal, which are increase by 4 at -# every cycle. The next four number added to the diagonal are 13 (9+4), 17 (9+4+4), 21 and 25. -# Then 25+6 etc., at every cycle the step is increased by 2. Continue until the ratio goes below 0.1. +@timing +def p058(): + # Starting with 1, the next four numbers in the diagonal are 3 (1+2), 5 (1+2+2), 7 (1+2+2+2) + # and 9 (1+2+2+2+2). Check which are prime, increment the counter every time a new prime is + # found, and divide by the number of elements of the diagonal, which are increase by 4 at + # every cycle. The next four number added to the diagonal are 13 (9+4), 17 (9+4+4), 21 and 25. + # Then 25+6 etc., at every cycle the step is increased by 2. Continue until the ratio goes below 0.1. i = 1 l = 1 step = 2 @@ -61,13 +58,9 @@ def main(): if ratio < 0.1: break - end = default_timer() - print('Project Euler, Problem 58') print(f'Answer: {l}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p058() diff --git a/Python/p059.py b/Python/p059.py index 6ce69a4..908cc33 100644 --- a/Python/p059.py +++ b/Python/p059.py @@ -18,7 +18,9 @@ # encrypted ASCII codes, and the knowledge that the plain text must contain common English words, decrypt the message and find the sum of the # ASCII values in the original text. -from timeit import default_timer +import sys + +from projecteuler import timing class EncryptedText(): @@ -40,16 +42,18 @@ class EncryptedText(): self.len = len(self.text) + return 0 + def decrypt(self): found = 0 for c1 in range(ord('a'), ord('z')+1): if found: - break + break for c2 in range(ord('a'), ord('z')+1): if found: break - + for c3 in range(ord('a'), ord('z')+1): if found: break @@ -57,16 +61,16 @@ class EncryptedText(): plain_text = [''] * self.len for i in range(0, self.len-2, 3): - plain_text[i] = str(chr(self.text[i]^c1)) - plain_text[i+1] = str(chr(self.text[i+1]^c2)) - plain_text[i+2] = str(chr(self.text[i+2]^c3)) + plain_text[i] = str(chr(self.text[i] ^ c1)) + plain_text[i+1] = str(chr(self.text[i+1] ^ c2)) + plain_text[i+2] = str(chr(self.text[i+2] ^ c3)) if i == self.len - 2: - plain_text[i] = str(chr(self.text[i]^c1)) - plain_text[i+1] = str(chr(self.text[i+1]^c2)) + plain_text[i] = str(chr(self.text[i] ^ c1)) + plain_text[i+1] = str(chr(self.text[i+1] ^ c2)) if i == self.len - 1: - plain_text[i] = str(chr(self.text[i]^c1)) + plain_text[i] = str(chr(self.text[i] ^ c1)) plain_text = ''.join(plain_text) @@ -77,9 +81,8 @@ class EncryptedText(): return plain_text -def main(): - start = default_timer() - +@timing +def p059(): enc_text = EncryptedText() if enc_text.read_text('p059_cipher.txt') == -1: @@ -92,13 +95,9 @@ def main(): for i in list(plain_text): sum_ = sum_ + ord(i) - end = default_timer() - print('Project Euler, Problem 59') print(f'Answer: {sum_}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p059() diff --git a/Python/p060.py b/Python/p060.py index 565fa6e..8a1ae92 100644 --- a/Python/p060.py +++ b/Python/p060.py @@ -6,14 +6,11 @@ # # Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. -from timeit import default_timer - -from projecteuler import sieve, is_prime +from projecteuler import is_prime, sieve, timing -def main(): - start = default_timer() - +@timing +def p060(): N = 10000 primes = sieve(N) @@ -21,9 +18,9 @@ def main(): found = 0 p1 = 3 -# Straightforward brute force approach + # Straightforward brute force approach while p1 < N and not found: -# If p1 is not prime, go to the next number. + # If p1 is not prime, go to the next number. if primes[p1] == 0: p1 = p1 + 2 continue @@ -31,8 +28,8 @@ def main(): p2 = p1 + 2 while p2 < N and not found: -# If p2 is not prime, or at least one of the possible concatenations of -# p1 and p2 is not prime, go to the next number. + # If p2 is not prime, or at least one of the possible concatenations of + # p1 and p2 is not prime, go to the next number. if primes[p2] == 0 or not is_prime(int(str(p1)+str(p2))) or not is_prime(int(str(p2)+str(p1))): p2 = p2 + 2 continue @@ -40,8 +37,8 @@ def main(): p3 = p2 + 2 while p3 < N and not found: -# If p3 is not prime, or at least one of the possible concatenations of -# p1, p2 and p3 is not prime, got to the next number. + # If p3 is not prime, or at least one of the possible concatenations of + # p1, p2 and p3 is not prime, got to the next number. if primes[p3] == 0 or not is_prime(int(str(p1)+str(p3))) or not is_prime(int(str(p3)+str(p1))) or\ not is_prime(int(str(p2)+str(p3))) or not is_prime(int(str(p3)+str(p2))): p3 = p3 + 2 @@ -51,8 +48,8 @@ def main(): p4 = p3 + 2 while p4 < N and not found: -# If p4 is not prime, or at least one of the possible concatenations of -# p1, p2, p3 and p4 is not prime, go to the next number. + # If p4 is not prime, or at least one of the possible concatenations of + # p1, p2, p3 and p4 is not prime, go to the next number. if primes[p4] == 0 or not is_prime(int(str(p1)+str(p4))) or not is_prime(int(str(p4)+str(p1))) or\ not is_prime(int(str(p2)+str(p4))) or not is_prime(int(str(p4)+str(p2))) or\ not is_prime(int(str(p3)+str(p4))) or not is_prime(int(str(p4)+str(p3))): @@ -63,8 +60,8 @@ def main(): p5 = p4 + 2 while p5 < N and not found: -# If p5 is not prime, or at least one of the possible concatenations of -# p1, p2, p3, p4 and p5 is not prime, go to the next number + # If p5 is not prime, or at least one of the possible concatenations of + # p1, p2, p3, p4 and p5 is not prime, go to the next number if primes[p5] == 0 or not is_prime(int(str(p1)+str(p5))) or not is_prime(int(str(p5)+str(p1))) or\ not is_prime(int(str(p2)+str(p5))) or not is_prime(int(str(p5)+str(p2))) or\ not is_prime(int(str(p3)+str(p5))) or not is_prime(int(str(p5)+str(p3))) or\ @@ -73,7 +70,7 @@ def main(): continue -# If it gets here, the five values have been found. + # If it gets here, the five values have been found. n = p1 + p2 + p3 + p4 + p5 found = 1 @@ -85,13 +82,9 @@ def main(): p1 = p1 + 2 - end = default_timer() - print('Project Euler, Problem 60') print(f'Answer: {n}') - print(f'Elapsed time: {end - start:.9f} seconds') - if __name__ == '__main__': - main() + p060()