From c624e6ac522209b40bd6f83c16d4f25d83be3c69 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Wed, 17 Jul 2019 21:29:59 -0400 Subject: [PATCH] Moved problems till 56 to Python. --- python/e046.py | 18 ++++- python/e047.py | 13 +++- python/e048.py | 4 +- python/e049.py | 35 ++++++++- python/e050.py | 29 ++++++- python/e051.py | 34 ++++++++- python/e052.py | 31 +++++++- python/e053.py | 15 +++- python/e054.py | 134 ++++++++++++++++++++++++++++++++- python/e055.py | 20 ++++- python/e056.py | 13 ++++ python/e057.py | 8 ++ python/e058.py | 8 ++ python/e059.py | 8 ++ python/e060.py | 8 ++ python/e061.py | 8 ++ python/e062.py | 8 ++ python/e063.py | 8 ++ python/e064.py | 8 ++ python/e065.py | 8 ++ python/e066.py | 8 ++ python/e068.py | 8 ++ python/lib_create_templates.py | 6 +- 23 files changed, 417 insertions(+), 23 deletions(-) create mode 100644 python/e056.py create mode 100644 python/e057.py create mode 100644 python/e058.py create mode 100644 python/e059.py create mode 100644 python/e060.py create mode 100644 python/e061.py create mode 100644 python/e062.py create mode 100644 python/e063.py create mode 100644 python/e064.py create mode 100644 python/e065.py create mode 100644 python/e066.py create mode 100644 python/e068.py diff --git a/python/e046.py b/python/e046.py index 1d240d1..55ef7c7 100644 --- a/python/e046.py +++ b/python/e046.py @@ -1,8 +1,22 @@ +from lib_prime import is_prime + def euler_046(): - return 0 + n_max = 10000 + twice_squares = [2 * n * n for n in range(1, n_max + 1)] + + def test_conjecture(n): + for ts in twice_squares: + if ts > n: + return False + if is_prime(n - ts): + return True + + for n in range(3, n_max + 1, 2): + if not is_prime(n) and test_conjecture(n) is False: + return n if __name__ == "__main__": print("e046.py: " + str(euler_046())) - assert(euler_046() == 0) + assert(euler_046() == 5777) diff --git a/python/e047.py b/python/e047.py index 3bff912..43b8581 100644 --- a/python/e047.py +++ b/python/e047.py @@ -1,8 +1,17 @@ +from lib_prime import prime_factors_count + def euler_047(): - return 0 + s = [] + for n in range(2, 1000000): + if len(prime_factors_count(n)) == 4: + s.append(n) + else: + s = [] + if len(s) == 4: + return s[0] if __name__ == "__main__": print("e047.py: " + str(euler_047())) - assert(euler_047() == 0) + assert(euler_047() == 134043) diff --git a/python/e048.py b/python/e048.py index b8d6bd1..8e95065 100644 --- a/python/e048.py +++ b/python/e048.py @@ -1,8 +1,8 @@ def euler_048(): - return 0 + return int(str(sum([i**i for i in range(1, 1001)]))[-10:]) if __name__ == "__main__": print("e048.py: " + str(euler_048())) - assert(euler_048() == 0) + assert(euler_048() == 9110846700) diff --git a/python/e049.py b/python/e049.py index 42bb5cc..70687f3 100644 --- a/python/e049.py +++ b/python/e049.py @@ -1,8 +1,39 @@ +from lib_prime import primes + def euler_049(): - return 0 + + def find_increasing_sequence(xs): + deltas = [(xs[j] - xs[i], i, j) + for i in range(0, len(xs) - 1) + for j in range(i + 1, len(xs)) + ] + d = {} + for delta, i, j in deltas: + if delta in d and d[delta][-1] == i: + d[delta].append(j) + else: + d[delta] = [i, j] + for delta, sequence in d.items(): + if len(sequence) == 3: + return [xs[index] for index in sequence] + return [] + + ps = [p for p in primes(10000) if p > 1000] + d = {} + for p in ps: + s = "".join(sorted(str(p))) + try: + d[s].append(p) + except KeyError: + d[s] = [p] + + pss = [value for key, value in d.items() if len(value) >= 3] + s = [find_increasing_sequence(ps) + for ps in pss if find_increasing_sequence(ps)] + return int("".join(map(str, s[1]))) if __name__ == "__main__": print("e049.py: " + str(euler_049())) - assert(euler_049() == 0) + assert(euler_049() == 296962999629) diff --git a/python/e050.py b/python/e050.py index c45c6ab..9326fd5 100644 --- a/python/e050.py +++ b/python/e050.py @@ -1,8 +1,33 @@ +from lib_prime import primes + + +def find_max_series(start_index, series_list, series_set): + """ Start at the given index and sum up consecutive primes + into total. If a total is in the series_set (i.e. a prime) then + store the current number of consecutive primes (length) and the total. + If the total exceeds the last value of the given primes no longer + sequence can be found. Return the max sequence length and total. """ + series_max = series_list[-1] + total_max = 0 + total = 0 + for i in range(start_index, len(series_list)): + total = total + series_list[i] + if total in series_set: + length = i - start_index + 1 + total_max = total + if total > series_max: + return (length, total_max) + def euler_050(): - return 0 + n_max = 1000000 + ps = primes(n_max) + ps_set = set(ps) + s = max([x for x in [find_max_series(i, ps, ps_set) + for i in range(0, len(ps))] if x]) + return s[1] if __name__ == "__main__": print("e050.py: " + str(euler_050())) - assert(euler_050() == 0) + assert(euler_050() == 997651) diff --git a/python/e051.py b/python/e051.py index e3383f7..5950521 100644 --- a/python/e051.py +++ b/python/e051.py @@ -1,8 +1,38 @@ +from itertools import combinations +from lib_prime import primes + + +def get_replacements(n): + n = str(n) + xss = [[i for i in range(0, len(n)) if n[i] == d] + for d in "0123456789"] + xss = [x + for xs in xss if xs + for i in range(1, len(xs) + 1) + for x in combinations(xs, i)] + xss = ["".join(['x' if i in xs else d for i, d in enumerate(n)]) + for xs in xss] + return xss + def euler_051(): - return 0 + replacements = {} + ps = primes(1000000) + for p in ps: + for r in get_replacements(p): + try: + replacements[r].append(p) + if len(replacements[r]) == 8: + # print(replacements[r]) + s = replacements[r][0] + return s + except KeyError: + replacements[r] = [p] + if p > 1000000: + break + return s if __name__ == "__main__": print("e051.py: " + str(euler_051())) - assert(euler_051() == 0) + assert(euler_051() == 121313) diff --git a/python/e052.py b/python/e052.py index 2af5a3b..e708689 100644 --- a/python/e052.py +++ b/python/e052.py @@ -1,8 +1,35 @@ +def get_digits_count(n): + digits_count = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + for d in str(n): + digits_count[int(d)] += 1 + return digits_count + + +assert(get_digits_count(1258744) == [0, 1, 1, 0, 2, 1, 0, 1, 1, 0]) + + +def check_if_multiples_contain_same_digits(n, max_multiple=2): + + def get_length(n): + return len(str(n)) + + n_digits_count = get_digits_count(n) + n_length = get_length(n) + n_multiple = n * max_multiple + while n != n_multiple: + if n_length != get_length(n_multiple) \ + or n_digits_count != get_digits_count(n_multiple): + return False + n_multiple -= n + return True + def euler_052(): - return 0 + for i in range(100000, 200000): + if check_if_multiples_contain_same_digits(i, 6): + return i if __name__ == "__main__": print("e052.py: " + str(euler_052())) - assert(euler_052() == 0) + assert(euler_052() == 142857) diff --git a/python/e053.py b/python/e053.py index fa5ee72..8cd302d 100644 --- a/python/e053.py +++ b/python/e053.py @@ -1,8 +1,19 @@ +import math + + +def combinations_naiv(n, r): + return math.factorial(n) // (math.factorial(r) * math.factorial(n - r)) + def euler_053(): - return 0 + count = 0 + for n in range(1, 101): + for r in range(1, n + 1): + if combinations_naiv(n, r) > 10**6: + count += 1 + return count if __name__ == "__main__": print("e053.py: " + str(euler_053())) - assert(euler_053() == 0) + assert(euler_053() == 4075) diff --git a/python/e054.py b/python/e054.py index 0bdc96a..d7a3c2e 100644 --- a/python/e054.py +++ b/python/e054.py @@ -1,8 +1,138 @@ +def suit_to_value(suit): + return { + "2": 2, + "3": 3, + "4": 4, + "5": 5, + "6": 6, + "7": 7, + "8": 8, + "9": 9, + "T": 10, + "J": 11, + "Q": 12, + "K": 13, + "A": 14, + }[suit] + + +assert(suit_to_value('K') == 13) + + +def is_flush(colors): + first_color = colors[0] + for color in colors: + if color != first_color: + return False + return True + + +assert(is_flush(["H", "H", "H", "H", "H"])) +assert(is_flush(["H", "H", "D", "H", "H"]) is False) + + +def is_straight(suits): + suits = sorted(suits) + first_suit = suits[0] + for suit in suits[1:]: + if first_suit + 1 != suit: + return False + first_suit = suit + return True + + +assert(is_straight([6, 3, 4, 5, 7])) +assert(is_straight([6, 3, 4, 5, 8]) is False) + + +def get_numbered_groups(ns): + """ Takes [0, 3, 0, 3, 1] and returns + [(2, 3), (2, 0), (1, 1)] + """ + rs = [] + current_group = [] + for n in sorted(ns, reverse=True): + if not current_group or n in current_group: + current_group.append(n) + else: + rs.append(current_group) + current_group = [n] + rs.append(current_group) + rs = sorted([(len(r), r[0]) for r in rs], reverse=True) + return rs + + +assert(get_numbered_groups([0, 3, 0, 3, 1]) == [(2, 3), (2, 0), (1, 1)]) + + +def rank(hand): + """ A hand must be provided as a list of two letter strings. + The first letter is the suit and the second the suit of a card. + + The function returns a tuple. The first value represents the hand as + an integer where 0 means high card and 9 means Straight Flush. The + second value is a list of integers ranking the value of the respective + rank. For example, a Royal Flush would be (9, [14, 13, 12, 11, 10]), + while 22aqj would be (1, [2, 2, 14, 12, 11]). By doing this we can + simply compare to hands by first comparing the rank itself and then + the list of integers. + + We get something like ["5H", "6S", "7S", "5C", "KD"]. + """ + + suits, colors = zip(*(map(lambda s: (s[0], s[1]), hand))) + suits = sorted(map(suit_to_value, suits)) + + flush = is_flush(colors) + straight = is_straight(suits) + numbered_suits = get_numbered_groups(suits) + if flush and straight: + return [8, numbered_suits] + if flush: + return [5, numbered_suits] + if straight: + return [4, numbered_suits] + if numbered_suits[0][0] == 4: + return [7, numbered_suits] + if numbered_suits[0][0] == 3 and numbered_suits[1][0] == 2: + return [6, numbered_suits] + if numbered_suits[0][0] == 3: + return [3, numbered_suits] + if numbered_suits[0][0] == 2 and numbered_suits[1][0] == 2: + return [2, numbered_suits] + if numbered_suits[0][0] == 2: + return [1, numbered_suits] + return [0, numbered_suits] + + +def read_hands(): + """ Reads a list of tuples where each field + in the tuple represents a hand. + """ + hands = [] + with open("../txt/EulerProblem054.txt", "r") as f: + for line in f.readlines(): + cards = line.strip().split(" ") + hands.append((cards[:5], cards[5:])) + return hands + def euler_054(): - return 0 + p1_wins = 0 + + for p1_hand, p2_hand in read_hands(): + if rank(p1_hand) > rank(p2_hand): + p1_wins += 1 + # msg = "P1 hand {} wins over P2 hand {}." + # print(msg.format(p1_hand, p2_hand)) + else: + pass + # msg = "P1 hand {} loses versus P2 hand {}." + # print(msg.format(p1_hand, p2_hand)) + + return p1_wins if __name__ == "__main__": print("e054.py: " + str(euler_054())) - assert(euler_054() == 0) + assert(euler_054() == 376) diff --git a/python/e055.py b/python/e055.py index 8cf4034..d3f7e79 100644 --- a/python/e055.py +++ b/python/e055.py @@ -1,8 +1,24 @@ +from lib_misc import is_palindrome + + +def get_digit_inverse(n): + return int(str(n)[::-1]) + + +def is_not_lychrel(n, iterations=50): + for i in range(0, iterations): + n = n + get_digit_inverse(n) + if is_palindrome(n): + return (i + 1) + return 0 + def euler_055(): - return 0 + lychrels = [n for n in range(1, 10000) if is_not_lychrel(n) == 0] + s = len(lychrels) + return s if __name__ == "__main__": print("e055.py: " + str(euler_055())) - assert(euler_055() == 0) + assert(euler_055() == 249) diff --git a/python/e056.py b/python/e056.py new file mode 100644 index 0000000..cf86533 --- /dev/null +++ b/python/e056.py @@ -0,0 +1,13 @@ +def get_digit_sum(n): + return sum(map(int, str(n))) + + +def euler_056(): + s = max([get_digit_sum(a**b) for a in range(1, 100) + for b in range(1, 100)]) + return s + + +if __name__ == "__main__": + print("e056.py: " + str(euler_056())) + assert(euler_056() == 972) diff --git a/python/e057.py b/python/e057.py new file mode 100644 index 0000000..0e834fc --- /dev/null +++ b/python/e057.py @@ -0,0 +1,8 @@ + +def euler_057(): + return 0 + + +if __name__ == "__main__": + print("e057.py: " + str(euler_057())) + assert(euler_057() == 0) diff --git a/python/e058.py b/python/e058.py new file mode 100644 index 0000000..243ff51 --- /dev/null +++ b/python/e058.py @@ -0,0 +1,8 @@ + +def euler_058(): + return 0 + + +if __name__ == "__main__": + print("e058.py: " + str(euler_058())) + assert(euler_058() == 0) diff --git a/python/e059.py b/python/e059.py new file mode 100644 index 0000000..c7c3f12 --- /dev/null +++ b/python/e059.py @@ -0,0 +1,8 @@ + +def euler_059(): + return 0 + + +if __name__ == "__main__": + print("e059.py: " + str(euler_059())) + assert(euler_059() == 0) diff --git a/python/e060.py b/python/e060.py new file mode 100644 index 0000000..8f41242 --- /dev/null +++ b/python/e060.py @@ -0,0 +1,8 @@ + +def euler_060(): + return 0 + + +if __name__ == "__main__": + print("e060.py: " + str(euler_060())) + assert(euler_060() == 0) diff --git a/python/e061.py b/python/e061.py new file mode 100644 index 0000000..0907f9d --- /dev/null +++ b/python/e061.py @@ -0,0 +1,8 @@ + +def euler_061(): + return 0 + + +if __name__ == "__main__": + print("e061.py: " + str(euler_061())) + assert(euler_061() == 0) diff --git a/python/e062.py b/python/e062.py new file mode 100644 index 0000000..5fe0d8e --- /dev/null +++ b/python/e062.py @@ -0,0 +1,8 @@ + +def euler_062(): + return 0 + + +if __name__ == "__main__": + print("e062.py: " + str(euler_062())) + assert(euler_062() == 0) diff --git a/python/e063.py b/python/e063.py new file mode 100644 index 0000000..b466e87 --- /dev/null +++ b/python/e063.py @@ -0,0 +1,8 @@ + +def euler_063(): + return 0 + + +if __name__ == "__main__": + print("e063.py: " + str(euler_063())) + assert(euler_063() == 0) diff --git a/python/e064.py b/python/e064.py new file mode 100644 index 0000000..c2d28af --- /dev/null +++ b/python/e064.py @@ -0,0 +1,8 @@ + +def euler_064(): + return 0 + + +if __name__ == "__main__": + print("e064.py: " + str(euler_064())) + assert(euler_064() == 0) diff --git a/python/e065.py b/python/e065.py new file mode 100644 index 0000000..25fd749 --- /dev/null +++ b/python/e065.py @@ -0,0 +1,8 @@ + +def euler_065(): + return 0 + + +if __name__ == "__main__": + print("e065.py: " + str(euler_065())) + assert(euler_065() == 0) diff --git a/python/e066.py b/python/e066.py new file mode 100644 index 0000000..8b3dd50 --- /dev/null +++ b/python/e066.py @@ -0,0 +1,8 @@ + +def euler_066(): + return 0 + + +if __name__ == "__main__": + print("e066.py: " + str(euler_066())) + assert(euler_066() == 0) diff --git a/python/e068.py b/python/e068.py new file mode 100644 index 0000000..660c15c --- /dev/null +++ b/python/e068.py @@ -0,0 +1,8 @@ + +def euler_068(): + return 0 + + +if __name__ == "__main__": + print("e068.py: " + str(euler_068())) + assert(euler_068() == 0) diff --git a/python/lib_create_templates.py b/python/lib_create_templates.py index a9505cf..62c8c1d 100644 --- a/python/lib_create_templates.py +++ b/python/lib_create_templates.py @@ -1,5 +1,5 @@ -FROM = 56 -TILL = 66 +FROM = 68 +TILL = 68 template = """ def euler_XXX(): @@ -12,7 +12,7 @@ if __name__ == "__main__": """ -for i in range(FROM, TILL): +for i in range(FROM, TILL + 1): e = "0" + str(i) filename = "e" + e + ".py" with open(filename, "w") as f: