Fix problem number
This commit is contained in:
parent
a311ea75f8
commit
7190721c5f
@ -15,34 +15,45 @@ from utils import timeit, list_primes, is_prime
|
||||
@timeit("Problem 51")
|
||||
def compute():
|
||||
"""
|
||||
By replacing the 1st digit of the 2-digit number *3, it turns out that
|
||||
By replacing the 1st digit of the 2-digit number *3, it turns out that
|
||||
six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.
|
||||
|
||||
By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit
|
||||
number is the first example having seven primes among the ten generated numbers,
|
||||
yielding the family:
|
||||
|
||||
56003, 56113, 56333, 56443, 56663, 56773, and 56993.
|
||||
|
||||
Consequently 56003, being the first member of this family, is the smallest prime
|
||||
By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit
|
||||
number is the first example having seven primes among the ten generated numbers,
|
||||
yielding the family:
|
||||
|
||||
56003, 56113, 56333, 56443, 56663, 56773, and 56993.
|
||||
|
||||
Consequently 56003, being the first member of this family, is the smallest prime
|
||||
with this property.
|
||||
|
||||
Find the smallest prime which, by replacing part of the number (not necessarily
|
||||
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.
|
||||
"""
|
||||
|
||||
|
||||
primes = sorted(set(list_primes(1_000_000)) - set(list_primes(57_000)))
|
||||
digits = {'0':[], '1':[], '2':[],'3':[], '4':[], '5':[],'6':[], '7':[], '8':[], '9':[]}
|
||||
digits = {
|
||||
"0": [],
|
||||
"1": [],
|
||||
"2": [],
|
||||
"3": [],
|
||||
"4": [],
|
||||
"5": [],
|
||||
"6": [],
|
||||
"7": [],
|
||||
"8": [],
|
||||
"9": [],
|
||||
}
|
||||
for d in digits.keys():
|
||||
for p in primes:
|
||||
p = str(p)
|
||||
if p.count(d) == 3 and p[-1] != d:
|
||||
digits[d].append(p)
|
||||
for d in {'0', '1', '2'}:
|
||||
for d in {"0", "1", "2"}:
|
||||
for p in digits[d]:
|
||||
res = 0
|
||||
i = 10
|
||||
for D in {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}-{d}:
|
||||
for D in {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"} - {d}:
|
||||
i -= 1
|
||||
q = int(p.replace(d, D))
|
||||
if is_prime(q) and q > 57_000:
|
||||
@ -55,4 +66,4 @@ def compute():
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(51):003d}: {compute()}")
|
||||
print(f"Result for Problem 51: {compute()}")
|
||||
|
@ -15,22 +15,25 @@ from utils import timeit
|
||||
@timeit("Problem 52")
|
||||
def compute():
|
||||
"""
|
||||
It can be seen that the number, 125874, and its double, 251748,
|
||||
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,
|
||||
Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x,
|
||||
and 6x, contain the same digits.
|
||||
"""
|
||||
|
||||
for number in range(123456, 1_000_000):
|
||||
if sorted(str(number)) \
|
||||
== sorted(str(2*number)) \
|
||||
== sorted(str(3*number)) \
|
||||
== sorted(str(4*number)) \
|
||||
== sorted(str(5*number)) == sorted(str(6*number)):
|
||||
if (
|
||||
sorted(str(number))
|
||||
== sorted(str(2 * number))
|
||||
== sorted(str(3 * number))
|
||||
== sorted(str(4 * number))
|
||||
== sorted(str(5 * number))
|
||||
== sorted(str(6 * number))
|
||||
):
|
||||
return number
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(52):003d}: {compute()}")
|
||||
print(f"Result for Problem 52: {compute()}")
|
||||
|
@ -27,7 +27,7 @@ def compute():
|
||||
It is not until
|
||||
, that a value exceeds one-million: (23 over 10) = 1144066.
|
||||
|
||||
How many, not necessarily distinct, values of (n over r) for 1<=n<=100, are greater than one-million?
|
||||
How many, not necessarily distinct, values of (n over r) for 1<=n<=100, are greater than one-million?
|
||||
"""
|
||||
|
||||
ans = 0
|
||||
@ -41,4 +41,4 @@ def compute():
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(53):003d}: {compute()}")
|
||||
print(f"Result for Problem 53: {compute()}")
|
||||
|
@ -16,7 +16,7 @@ from utils import timeit
|
||||
@timeit("Problem 54")
|
||||
def compute():
|
||||
"""
|
||||
In the card game poker, a hand consists of five cards and are ranked,
|
||||
In the card game poker, a hand consists of five cards and are ranked,
|
||||
from lowest to highest, in the following way:
|
||||
|
||||
High Card: Highest value card.
|
||||
@ -34,11 +34,11 @@ def compute():
|
||||
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
|
||||
|
||||
If two players have the same ranked hands then the rank made up of the
|
||||
highest value wins; for example, a pair of eights beats a pair of fives
|
||||
(see example 1 below). But if two ranks tie, for example, both players
|
||||
have a pair of queens, then highest cards in each hand are compared
|
||||
(see example 4 below); if the highest cards tie then the next highest
|
||||
If two players have the same ranked hands then the rank made up of the
|
||||
highest value wins; for example, a pair of eights beats a pair of fives
|
||||
(see example 1 below). But if two ranks tie, for example, both players
|
||||
have a pair of queens, then highest cards in each hand are compared
|
||||
(see example 4 below); if the highest cards tie then the next highest
|
||||
cards are compared, and so on.
|
||||
|
||||
Consider the following five hands dealt to two players:
|
||||
@ -56,12 +56,12 @@ def compute():
|
||||
5 2H 2D 4C 4D 4S 3C 3D 3S 9S 9D Player 1
|
||||
Full House Full House
|
||||
With Three Fours with Three Threes
|
||||
|
||||
The file, poker.txt, contains one-thousand random hands dealt to two
|
||||
players. Each line of the file contains ten cards (separated by a single
|
||||
space): the first five are Player 1's cards and the last five are Player
|
||||
2's cards. 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
|
||||
|
||||
The file, poker.txt, contains one-thousand random hands dealt to two
|
||||
players. Each line of the file contains ten cards (separated by a single
|
||||
space): the first five are Player 1's cards and the last five are Player
|
||||
2's cards. 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?
|
||||
@ -79,7 +79,6 @@ def compute():
|
||||
def to_numerical(hand: list) -> list:
|
||||
return sorted([int(x[:-1]) for x in hand], reverse=True)
|
||||
|
||||
|
||||
# 10 Ranks functions.
|
||||
def high_card(str_hand: list) -> list:
|
||||
return to_numerical(str_hand)
|
||||
@ -87,7 +86,7 @@ def compute():
|
||||
def one_pair(hand: list) -> int:
|
||||
return n_of_a_kind(hand, 2)
|
||||
|
||||
def two_pair(hand: list) -> int:
|
||||
def two_pair(hand: list) -> int:
|
||||
pairs = set([x for x in hand if hand.count(x) == 2])
|
||||
return 0 if len(pairs) < 2 else max(pairs)
|
||||
|
||||
@ -95,7 +94,7 @@ def compute():
|
||||
return n_of_a_kind(hand, 3)
|
||||
|
||||
def straight(hand: list) -> int:
|
||||
return 0 if not list(range(hand[0], hand[-1]-1, -1)) == hand else max(hand)
|
||||
return 0 if not list(range(hand[0], hand[-1] - 1, -1)) == hand else max(hand)
|
||||
|
||||
def flush(str_hand: list) -> bool:
|
||||
return len(set([x[-1] for x in str_hand])) == 1
|
||||
@ -113,7 +112,6 @@ def compute():
|
||||
def royal_flush(str_hand: list) -> bool:
|
||||
return flush(str_hand) and list(range(14, 9, -1)) == to_numerical(str_hand)
|
||||
|
||||
|
||||
replace_map = {"T": 10, "J": 11, "Q": 12, "K": 13, "A": 14}
|
||||
score = [0, 0]
|
||||
|
||||
@ -121,10 +119,25 @@ def compute():
|
||||
for line in open(file, "r").read().splitlines():
|
||||
line = replace_values_in_string(line, replace_map).split()
|
||||
hands = line[:5], line[5:]
|
||||
for rank in (royal_flush, straight_flush, four_of_a_kind, full_house, flush,
|
||||
straight, three_of_a_kind, two_pair, one_pair, high_card):
|
||||
should_convert_hand = "str" not in rank.__code__.co_varnames[0] # Checks parameter name.
|
||||
result = [rank(to_numerical(hand) if should_convert_hand else hand) for hand in hands]
|
||||
for rank in (
|
||||
royal_flush,
|
||||
straight_flush,
|
||||
four_of_a_kind,
|
||||
full_house,
|
||||
flush,
|
||||
straight,
|
||||
three_of_a_kind,
|
||||
two_pair,
|
||||
one_pair,
|
||||
high_card,
|
||||
):
|
||||
should_convert_hand = (
|
||||
"str" not in rank.__code__.co_varnames[0]
|
||||
) # Checks parameter name.
|
||||
result = [
|
||||
rank(to_numerical(hand) if should_convert_hand else hand)
|
||||
for hand in hands
|
||||
]
|
||||
if result[0] != result[1]:
|
||||
score[0 if result[0] > result[1] else 1] += 1
|
||||
break
|
||||
@ -134,4 +147,4 @@ def compute():
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(54):003d}: {compute()}")
|
||||
print(f"Result for Problem 54: {compute()}")
|
||||
|
@ -31,13 +31,13 @@ def compute():
|
||||
of these numbers, and for the purpose of this problem, we shall assume that a
|
||||
number is Lychrel until proven otherwise. In addition you are given that for
|
||||
every number below ten-thousand, it will either:
|
||||
(i) become a palindrome in less than fifty iterations, or,
|
||||
(i) become a palindrome in less than fifty iterations, or,
|
||||
(ii) no one, with all the computing power that exists, has managed so far to map
|
||||
it to a palindrome.
|
||||
|
||||
|
||||
In fact, 10677 is the first number to be shown to require over fifty iterations
|
||||
before producing a palindrome:
|
||||
|
||||
|
||||
4668731596684224866951378664 (53 iterations, 28-digits).
|
||||
|
||||
Surprisingly, there are palindromic numbers that are themselves Lychrel numbers;
|
||||
@ -57,10 +57,10 @@ def compute():
|
||||
break
|
||||
if is_lychrel:
|
||||
ans += 1
|
||||
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(55):003d}: {compute()}")
|
||||
print(f"Result for Problem 55: {compute()}")
|
||||
|
@ -15,7 +15,7 @@ from utils import timeit
|
||||
@timeit("Problem 56")
|
||||
def compute():
|
||||
"""
|
||||
A googol (10^100) is a massive number: one followed by one-hundred zeros;
|
||||
A googol (10^100) is a massive number: one followed by one-hundred zeros;
|
||||
100100 is almost unimaginably large: one followed by two-hundred zeros.
|
||||
Despite their size, the sum of the digits in each number is only 1.
|
||||
|
||||
@ -26,7 +26,7 @@ def compute():
|
||||
ans = 0
|
||||
for a in range(100):
|
||||
for b in range(100):
|
||||
num = sum([int(digit) for digit in str(a**b)])
|
||||
num = sum([int(digit) for digit in str(a ** b)])
|
||||
if num > ans:
|
||||
ans = num
|
||||
|
||||
@ -35,4 +35,4 @@ def compute():
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(56):003d}: {compute()}")
|
||||
print(f"Result for Problem 56: {compute()}")
|
||||
|
@ -16,7 +16,7 @@ from utils import timeit
|
||||
@timeit("Problem 57")
|
||||
def compute():
|
||||
"""
|
||||
It is possible to show that the square root of two can be expressed
|
||||
It is possible to show that the square root of two can be expressed
|
||||
as an infinite continued fraction.
|
||||
|
||||
By expanding this for the first four iterations, we get:
|
||||
@ -26,11 +26,11 @@ def compute():
|
||||
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 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
|
||||
In the first one-thousand expansions, how many fractions contain a numerator
|
||||
with more digits than the denominator?
|
||||
"""
|
||||
|
||||
@ -41,10 +41,10 @@ def compute():
|
||||
result = 1 + f
|
||||
if len(str(result.numerator)) > len(str(result.denominator)):
|
||||
ans += 1
|
||||
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(57):003d}: {compute()}")
|
||||
print(f"Result for Problem 57: {compute()}")
|
||||
|
@ -15,7 +15,7 @@ from utils import timeit, is_prime
|
||||
@timeit("Problem 58")
|
||||
def compute():
|
||||
"""
|
||||
Starting with 1 and spiralling anticlockwise in the following way,
|
||||
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
|
||||
@ -26,13 +26,13 @@ def compute():
|
||||
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
|
||||
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
|
||||
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%?
|
||||
"""
|
||||
|
||||
@ -53,4 +53,4 @@ def compute():
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(58):003d}: {compute()}")
|
||||
print(f"Result for Problem 58: {compute()}")
|
||||
|
@ -17,37 +17,37 @@ from utils import timeit
|
||||
@timeit("Problem 59")
|
||||
def compute():
|
||||
"""
|
||||
Each character on a computer is assigned a unique code and the preferred
|
||||
standard is ASCII (American Standard Code for Information Interchange).
|
||||
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,
|
||||
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
|
||||
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
|
||||
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 p059_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
|
||||
Your task has been made easy, as the encryption key consists of three
|
||||
lower case characters. Using p059_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.
|
||||
"""
|
||||
|
||||
with open('../files/Problem59.txt', 'r') as f:
|
||||
with open("../files/Problem59.txt", "r") as f:
|
||||
# encrypted = list(map(int, f.read().split(',')))
|
||||
encrypted = [int(char) for char in f.read().split(',')]
|
||||
encrypted = [int(char) for char in f.read().split(",")]
|
||||
# print(encrypted)
|
||||
# print(test)
|
||||
plain_text = len(encrypted) // 3
|
||||
@ -55,12 +55,12 @@ def compute():
|
||||
decrypted = ""
|
||||
for k, i in zip(list(key) * plain_text, encrypted):
|
||||
decrypted += chr(ord(k) ^ i)
|
||||
|
||||
|
||||
# assuming Euler will be in the text
|
||||
if 'Euler' in decrypted:
|
||||
if "Euler" in decrypted:
|
||||
return sum([ord(c) for c in decrypted])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"Result for Problem {int(59):003d}: {compute()}")
|
||||
print(f"Result for Problem 59: {compute()}")
|
||||
|
48
src/Python/Problems001-050/utils.py
Normal file
48
src/Python/Problems001-050/utils.py
Normal file
@ -0,0 +1,48 @@
|
||||
import math
|
||||
from functools import wraps
|
||||
|
||||
|
||||
def timeit(name):
|
||||
def profile(original):
|
||||
import time
|
||||
@wraps(original)
|
||||
def wrapper(*args, **kwargs):
|
||||
t0 = time.perf_counter()
|
||||
result = original(*args, **kwargs)
|
||||
t1 = time.perf_counter()
|
||||
print(f"Time to evaluate problem {int(name[7:]):003d}: {(t1 - t0)*1000:.3f} ms\n")
|
||||
return result
|
||||
return wrapper
|
||||
return profile
|
||||
|
||||
|
||||
def is_prime(n):
|
||||
if n <2:
|
||||
return False
|
||||
for i in range(2, int(math.sqrt(n)) + 1):
|
||||
if n % i == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# Returns a list of True and False indicating whether each number is prime.
|
||||
# For 0 <= i <= n, result[i] is True if i is a prime number, False otherwise.
|
||||
def list_primality(n):
|
||||
# Sieve of Eratosthenes
|
||||
result = [True] * (n + 1)
|
||||
result[0] = result[1] = False
|
||||
for i in range(int(math.sqrt(n) + 1)):
|
||||
if result[i]:
|
||||
for j in range(i * i, len(result), i):
|
||||
result[j] = False
|
||||
return result
|
||||
|
||||
|
||||
# Returns all the prime numbers less than or equal to n, in ascending order
|
||||
# For example: list_primes(97) = [2, 3, 5, 7, 11, ..., 83, 89, 97].
|
||||
def list_primes(n):
|
||||
return [i for (i, is_prime) in enumerate(list_primality(n)) if is_prime]
|
||||
|
||||
|
||||
def is_palindrome(num):
|
||||
return str(num) == str(num)[::-1]
|
Loading…
x
Reference in New Issue
Block a user