From e7002254e2b434f0b87f9371d7496df795f74758 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Fri, 14 May 2021 20:17:59 -0400 Subject: [PATCH] Solve problem 98 --- python/e098.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 python/e098.py diff --git a/python/e098.py b/python/e098.py new file mode 100644 index 0000000..258d6db --- /dev/null +++ b/python/e098.py @@ -0,0 +1,88 @@ + +def get_words(): + with open("../txt/e098.txt", "r") as f: + words = list(map(lambda w: w.strip().lower(), f.readlines())) + words.sort(key=len, reverse=True) + return words + + +def get_pair_subsets(xs): + """ Returns all subsets of size two. """ + r = [(xs[i], xs[j]) + for i in range(len(xs)) + for j in range(i + 1, len(xs))] + return r + + +def find_anagrams(xs): + anagrams = {} + for x in xs: + x_tuple = tuple(sorted(x)) + try: + anagrams[x_tuple].append(x) + except KeyError: + anagrams[x_tuple] = [x] + anagrams = [a for a in anagrams.values() if len(a) > 1] + return anagrams + + +def find_anagram_pairs(xs): + anagrams = find_anagrams(xs) + r = [pair + for anagram in anagrams + for pair in get_pair_subsets(anagram)] + return r + + +def words_match_numbers(words, numbers): + letters_a, letters_b = words + digits_a, digits_b = numbers + + digit_to_letter = {} + for l, d in zip(letters_a, digits_a): + if d in digit_to_letter and digit_to_letter[d] != l: + # Each digit can only be assigned to one letter + return False + digit_to_letter[d] = l + + + letter_to_digit = {l: d for l, d in zip(letters_a, digits_a)} + for l, d in zip(letters_b, digits_b): + if letter_to_digit[l] != d: + return False + return True + + +def find_pairs(words, squares): + pairs = [] + anagram_pairs = find_anagram_pairs(words) + square_pairs = find_anagram_pairs(squares) + for word_pair in anagram_pairs: + for number_pair in square_pairs: + if words_match_numbers(word_pair, number_pair): + # pairs.append([word_pair, number_pair]) + pairs.append(number_pair) + return pairs + + +def euler_098(): + squares = [str(i * i) for i in range(200000)] + words = get_words() + + largest_number = 0 + for i in range(3, 9): + words_i = list(filter(lambda w: len(w) == i, words)) + squares_i = list(filter(lambda w: len(w) == i, squares)) + pairs = find_pairs(words_i, squares_i) + for pair in pairs: + n = max(map(int, pair)) + if n > largest_number: + largest_number = n + return largest_number + + +if __name__ == "__main__": + solution = euler_098() + print("e098.py: " + str(solution)) + assert(solution == 18769) +