Add more solutions in python

Added python solutions for problem 56, 57, 58, 59 and 60
This commit is contained in:
daniele 2019-09-27 15:16:09 +02:00
parent 9e8d530d9e
commit ed7031df4d
Signed by: fuxino
GPG Key ID: 6FE25B4A3EE16FDA
12 changed files with 358 additions and 5 deletions

View File

@ -122,6 +122,7 @@ int main(int argc, char **argv)
}
found = 1;
printf("%c%c%c\n", c1, c2, c3);
}
}
}

View File

@ -29,7 +29,7 @@ int main(int argc, char **argv)
/* Straightforward brute force approach.*/
for(p1 = 3; p1 < N && !found; p1 += 2)
{
/* If p1 is not prime, go to next number.*/
/* If p1 is not prime, go to the next number.*/
if(!primes[p1])
{
continue;

1
Python/cipher.txt Normal file
View File

@ -0,0 +1 @@
36,22,80,0,0,4,23,25,19,17,88,4,4,19,21,11,88,22,23,23,29,69,12,24,0,88,25,11,12,2,10,28,5,6,12,25,10,22,80,10,30,80,10,22,21,69,23,22,69,61,5,9,29,2,66,11,80,8,23,3,17,88,19,0,20,21,7,10,17,17,29,20,69,8,17,21,29,2,22,84,80,71,60,21,69,11,5,8,21,25,22,88,3,0,10,25,0,10,5,8,88,2,0,27,25,21,10,31,6,25,2,16,21,82,69,35,63,11,88,4,13,29,80,22,13,29,22,88,31,3,88,3,0,10,25,0,11,80,10,30,80,23,29,19,12,8,2,10,27,17,9,11,45,95,88,57,69,16,17,19,29,80,23,29,19,0,22,4,9,1,80,3,23,5,11,28,92,69,9,5,12,12,21,69,13,30,0,0,0,0,27,4,0,28,28,28,84,80,4,22,80,0,20,21,2,25,30,17,88,21,29,8,2,0,11,3,12,23,30,69,30,31,23,88,4,13,29,80,0,22,4,12,10,21,69,11,5,8,88,31,3,88,4,13,17,3,69,11,21,23,17,21,22,88,65,69,83,80,84,87,68,69,83,80,84,87,73,69,83,80,84,87,65,83,88,91,69,29,4,6,86,92,69,15,24,12,27,24,69,28,21,21,29,30,1,11,80,10,22,80,17,16,21,69,9,5,4,28,2,4,12,5,23,29,80,10,30,80,17,16,21,69,27,25,23,27,28,0,84,80,22,23,80,17,16,17,17,88,25,3,88,4,13,29,80,17,10,5,0,88,3,16,21,80,10,30,80,17,16,25,22,88,3,0,10,25,0,11,80,12,11,80,10,26,4,4,17,30,0,28,92,69,30,2,10,21,80,12,12,80,4,12,80,10,22,19,0,88,4,13,29,80,20,13,17,1,10,17,17,13,2,0,88,31,3,88,4,13,29,80,6,17,2,6,20,21,69,30,31,9,20,31,18,11,94,69,54,17,8,29,28,28,84,80,44,88,24,4,14,21,69,30,31,16,22,20,69,12,24,4,12,80,17,16,21,69,11,5,8,88,31,3,88,4,13,17,3,69,11,21,23,17,21,22,88,25,22,88,17,69,11,25,29,12,24,69,8,17,23,12,80,10,30,80,17,16,21,69,11,1,16,25,2,0,88,31,3,88,4,13,29,80,21,29,2,12,21,21,17,29,2,69,23,22,69,12,24,0,88,19,12,10,19,9,29,80,18,16,31,22,29,80,1,17,17,8,29,4,0,10,80,12,11,80,84,67,80,10,10,80,7,1,80,21,13,4,17,17,30,2,88,4,13,29,80,22,13,29,69,23,22,69,12,24,12,11,80,22,29,2,12,29,3,69,29,1,16,25,28,69,12,31,69,11,92,69,17,4,69,16,17,22,88,4,13,29,80,23,25,4,12,23,80,22,9,2,17,80,70,76,88,29,16,20,4,12,8,28,12,29,20,69,26,9,69,11,80,17,23,80,84,88,31,3,88,4,13,29,80,21,29,2,12,21,21,17,29,2,69,12,31,69,12,24,0,88,20,12,25,29,0,12,21,23,86,80,44,88,7,12,20,28,69,11,31,10,22,80,22,16,31,18,88,4,13,25,4,69,12,24,0,88,3,16,21,80,10,30,80,17,16,25,22,88,3,0,10,25,0,11,80,17,23,80,7,29,80,4,8,0,23,23,8,12,21,17,17,29,28,28,88,65,75,78,68,81,65,67,81,72,70,83,64,68,87,74,70,81,75,70,81,67,80,4,22,20,69,30,2,10,21,80,8,13,28,17,17,0,9,1,25,11,31,80,17,16,25,22,88,30,16,21,18,0,10,80,7,1,80,22,17,8,73,88,17,11,28,80,17,16,21,11,88,4,4,19,25,11,31,80,17,16,21,69,11,1,16,25,2,0,88,2,10,23,4,73,88,4,13,29,80,11,13,29,7,29,2,69,75,94,84,76,65,80,65,66,83,77,67,80,64,73,82,65,67,87,75,72,69,17,3,69,17,30,1,29,21,1,88,0,23,23,20,16,27,21,1,84,80,18,16,25,6,16,80,0,0,0,23,29,3,22,29,3,69,12,24,0,88,0,0,10,25,8,29,4,0,10,80,10,30,80,4,88,19,12,10,19,9,29,80,18,16,31,22,29,80,1,17,17,8,29,4,0,10,80,12,11,80,84,86,80,35,23,28,9,23,7,12,22,23,69,25,23,4,17,30,69,12,24,0,88,3,4,21,21,69,11,4,0,8,3,69,26,9,69,15,24,12,27,24,69,49,80,13,25,20,69,25,2,23,17,6,0,28,80,4,12,80,17,16,25,22,88,3,16,21,92,69,49,80,13,25,6,0,88,20,12,11,19,10,14,21,23,29,20,69,12,24,4,12,80,17,16,21,69,11,5,8,88,31,3,88,4,13,29,80,22,29,2,12,29,3,69,73,80,78,88,65,74,73,70,69,83,80,84,87,72,84,88,91,69,73,95,87,77,70,69,83,80,84,87,70,87,77,80,78,88,21,17,27,94,69,25,28,22,23,80,1,29,0,0,22,20,22,88,31,11,88,4,13,29,80,20,13,17,1,10,17,17,13,2,0,88,31,3,88,4,13,29,80,6,17,2,6,20,21,75,88,62,4,21,21,9,1,92,69,12,24,0,88,3,16,21,80,10,30,80,17,16,25,22,88,29,16,20,4,12,8,28,12,29,20,69,26,9,69,65,64,69,31,25,19,29,3,69,12,24,0,88,18,12,9,5,4,28,2,4,12,21,69,80,22,10,13,2,17,16,80,21,23,7,0,10,89,69,23,22,69,12,24,0,88,19,12,10,19,16,21,22,0,10,21,11,27,21,69,23,22,69,12,24,0,88,0,0,10,25,8,29,4,0,10,80,10,30,80,4,88,19,12,10,19,9,29,80,18,16,31,22,29,80,1,17,17,8,29,4,0,10,80,12,11,80,84,86,80,36,22,20,69,26,9,69,11,25,8,17,28,4,10,80,23,29,17,22,23,30,12,22,23,69,49,80,13,25,6,0,88,28,12,19,21,18,17,3,0,88,18,0,29,30,69,25,18,9,29,80,17,23,80,1,29,4,0,10,29,12,22,21,69,12,24,0,88,3,16,21,3,69,23,22,69,12,24,0,88,3,16,26,3,0,9,5,0,22,4,69,11,21,23,17,21,22,88,25,11,88,7,13,17,19,13,88,4,13,29,80,0,0,0,10,22,21,11,12,3,69,25,2,0,88,21,19,29,30,69,22,5,8,26,21,23,11,94

View File

@ -7,7 +7,7 @@
# family, is the smallest prime with this property.
#
# 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.*/
# value family.
from timeit import default_timer
from projecteuler import sieve

View File

@ -2,7 +2,7 @@
# It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order.
#
# Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits.*
# Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits.
from numpy import zeros

View File

@ -44,7 +44,7 @@
# You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order,
# and in each hand there is a clear winner.
#
# How many hands does Player 1 win?*/
# How many hands does Player 1 win?
from enum import IntEnum

View File

@ -21,7 +21,7 @@
#
# How many Lychrel numbers are there below ten-thousand?
#
# NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers.*/
# 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

36
Python/p056.py Normal file
View File

@ -0,0 +1,36 @@
#!/usr/bin/python
# A googol (10^100) is a massive number: one followed by one-hundred zeros; 100^100 is almost unimaginably large: one followed by two-hundred zeros.
# Despite their size, the sum of the digits in each number is only 1.
#
# Considering natural numbers of the form, a^b, where a, b < 100, what is the maximum digital sum?
from timeit import default_timer
def main():
start = default_timer()
max_ = 0
# Straightforward brute force approach
for a in range(1, 100):
for b in range(1, 100):
p = a ** b
sum_ = 0
while p > 0:
sum_ = sum_ + p % 10
p = p // 10
if sum_ > max_:
max_ = sum_
end = default_timer()
print('Project Euler, Problem 56')
print('Answer: {}'.format(max_))
print('Elapsed time: {:.9f} seconds'.format(end - start))
if __name__ == '__main__':
main()

55
Python/p057.py Normal file
View File

@ -0,0 +1,55 @@
#!/usr/bin/python
# It is possible to show that the square root of two can be expressed as an infinite continued fraction.
#
# √2=1+1/(2+1/(2+1/(2+…
#
# By expanding this for the first four iterations, we get:
#
# 1+1/2=3/2=1.5
# 1+1/(2+1/2)=7/5=1.4
# 1+1/(2+1/(2+1/2))=17/12=1.41666…
# 1+1/(2+1/(2+1/(2+1/2)))=41/29=1.41379…
#
# The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985, is the first example where the number of digits
# in the numerator exceeds the number of digits in the denominator.
#
# In the first one-thousand expansions, how many fractions contain a numerator with more digits than the denominator?
from timeit import default_timer
def count_digits(n):
count = 0
while n > 0:
n = n // 10
count = count + 1
return count
def main():
start = default_timer()
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).
for i in range(1, 1000):
d2 = 2 * d
d = n + d
n = n + d2
if count_digits(n) > count_digits(d):
count = count + 1
end = default_timer()
print('Project Euler, Problem 57')
print('Answer: {}'.format(count))
print('Elapsed time: {:.9f} seconds'.format(end - start))
if __name__ == '__main__':
main()

70
Python/p058.py Normal file
View File

@ -0,0 +1,70 @@
#!/usr/bin/python
# Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.
#
# 37 36 35 34 33 32 31
# 38 17 16 15 14 13 30
# 39 18 5 4 3 12 29
# 40 19 6 1 2 11 28
# 41 20 7 8 9 10 27
# 42 21 22 23 24 25 26
# 43 44 45 46 47 48 49
#
# It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers
# lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.
#
# 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
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.
i = 1
l = 1
step = 2
count = 0
diag = 5
while 1:
i = i + step
if is_prime(i):
count = count + 1
i = i + step
if is_prime(i):
count = count + 1
i = i + step
if is_prime(i):
count = count + 1
i = i + step
ratio = count / diag
step = step + 2
diag = diag + 4
l = l + 2
if ratio < 0.1:
break
end = default_timer()
print('Project Euler, Problem 58')
print('Answer: {}'.format(l))
print('Elapsed time: {:.9f} seconds'.format(end - start))
if __name__ == '__main__':
main()

99
Python/p059.py Normal file
View File

@ -0,0 +1,99 @@
#!/usr/bin/python
# Each character on a computer is assigned a unique code and the preferred standard is ASCII (American Standard Code for Information Interchange).
# For example, uppercase A = 65, asterisk (*) = 42, and lowercase k = 107.
#
# A modern encryption method is to take a text file, convert the bytes to ASCII, then XOR each byte with a given value, taken from a secret key.
# The advantage with the XOR function is that using the same encryption key on the cipher text, restores the plain text; for example, 65 XOR 42 = 107,
# then 107 XOR 42 = 65.
#
# For unbreakable encryption, the key is the same length as the plain text message, and the key is made up of random bytes. The user would keep
# the encrypted message and the encryption key in different locations, and without both "halves", it is impossible to decrypt the message.
#
# Unfortunately, this method is impractical for most users, so the modified method is to use a password as a key. If the password is shorter than
# the message, which is likely, the key is repeated cyclically throughout the message. The balance for this method is using a sufficiently long
# password key for security, but short enough to be memorable.
#
# Your task has been made easy, as the encryption key consists of three lower case characters. Using cipher.txt, a file containing the
# 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
class EncryptedText():
def __init__(self, *args, **kwargs):
super(EncryptedText, self).__init__(*args, **kwargs)
self.text = None
self.len = 0
def read_text(self, filename):
try:
fp = open(filename, 'r')
except:
print('Error while opening file {}'.format(filename))
return -1
self.text = list(map(int, list(fp.readline().split(','))))
self.len = len(self.text)
fp.close()
def decrypt(self):
found = 0
for c1 in range(ord('a'), ord('z')+1):
if found:
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
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))
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))
if i == self.len - 1:
plain_text[i] = str(chr(self.text[i]^c1))
plain_text = ''.join(plain_text)
if 'the' in plain_text and 'be' in plain_text and 'to' in plain_text and 'of' in plain_text and\
'and' in plain_text and 'in' in plain_text and 'that' in plain_text and 'have' in plain_text:
found = 1
return plain_text
def main():
start = default_timer()
enc_text = EncryptedText()
if enc_text.read_text('cipher.txt') == -1:
exit(1)
plain_text = enc_text.decrypt()
sum_ = 0
for i in list(plain_text):
sum_ = sum_ + ord(i)
end = default_timer()
print('Project Euler, Problem 59')
print('Answer: {}'.format(sum_))
print('Elapsed time: {:.9f} seconds'.format(end - start))
if __name__ == '__main__':
main()

91
Python/p060.py Normal file
View File

@ -0,0 +1,91 @@
#!/usr/bin/python
# The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime.
# For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes
# with this property.
#
# 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
def main():
start = default_timer()
N = 10000
primes = sieve(N)
found = 0
p1 = 3
# Straightforward brute force approach
while p1 < N and not found:
# If p1 is not prime, go to the next number.
if primes[p1] == 0:
p1 = p1 + 2
continue
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 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
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 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
continue
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 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))):
p4 = p4 + 2
continue
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 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\
not is_prime(int(str(p4)+str(p5))) or not is_prime(int(str(p5)+str(p4))):
p5 = p5 + 2
continue
# If it gets here, the five values have been found.
n = p1 + p2 + p3 + p4 + p5
found = 1
p4 = p4 + 2
p3 = p3 + 2
p2 = p2 + 2
p1 = p1 + 2
end = default_timer()
print('Project Euler, Problem 59')
print('Answer: {}'.format(n))
print('Elapsed time: {:.9f} seconds'.format(end - start))
if __name__ == '__main__':
main()