Use timing decorator for problems 41-60

This commit is contained in:
daniele 2023-06-07 20:13:19 +02:00
parent be5e97dfbb
commit 5b99c1ef1c
Signed by: fuxino
GPG Key ID: 981A2B2A3BBF5514
20 changed files with 218 additions and 333 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()