from math import sqrt, ceil # is x anagram of y? def anagram(x, y): x2 = [c for c in x] y2 = [c for c in y] x2.sort() y2.sort() return x2 == y2 # returns replacement list def replacement(word, number): digits = [False] * 10 for char in word[::-1]: digit = number % 10 number /= 10 if char in digits and digits[digit] != char: return None if digits[digit] == False: digits[digit] = char elif digits[digit] != char: return None return digits # find numbers matching the specified word in descending order def match(word, numbers): result = [] for n in numbers: digits = replacement(word, n) if digits != None: result.append(n) result.sort(reverse=True) return result f = open('098.txt', 'r') words = f.read() f.close() maxlen = 14 words = set([ w.strip('"') for w in words.split(',') ]) squares = [ [ x*x for x in xrange(int(ceil(sqrt(10**n)))-1, int(ceil(sqrt(10**(n-1))))-1, -1) ] for n in xrange(1, maxlen+1) ] maxsquare = 0 for l in xrange(1, maxlen+1): cur = [ w for w in words if len(w) == l ] for word1 in cur: for word2 in cur: if word1 == word2 or word1 == word2[::-1] or not anagram(word1, word2): continue m1 = match(word1, squares[l-1]) m2 = match(word2, squares[l-1]) # compare result lists for n1 in m1: found = False for n2 in m2: if replacement(word1, n1) == replacement(word2, n2): #print word1, word2, n1, n2 if n1 > maxsquare: maxsquare = n1 found = True break if found: break print maxsquare