Solve problem 98
parent
40b07875ab
commit
e7002254e2
|
@ -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)
|
||||
|
Loading…
Reference in New Issue