euler/python/e098.py

89 lines
2.3 KiB
Python
Raw Normal View History

2021-05-15 02:17:59 +02:00
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)