def get_file(fn): with open(fn, 'r') as f: return list(map(lambda x: x[1:-1], f.read().split(','))) def get_pair(lst): for i in range(len(lst) - 1): for j in range(i + 1, len(lst)): yield (lst[i], lst[j]) def calc_rearray(pair): def do_iter(para): repeat = {} for ch in para[0]: map_index = para[1].find(ch, repeat.setdefault(ch, 0)) yield map_index repeat[ch] = map_index + 1 return tuple(do_iter(pair)) def reverse_rearray(map_rearray): def do_iter(para): for i in sorted(para): yield para.index(i) return tuple(do_iter(map_rearray)) def word_rearray(lst): pick = {} for item in lst: s_item = ''.join(sorted(item)) pick.setdefault(s_item, []).append(item) result = {} while len(pick): key, value = pick.popitem() if len(value) > 1: for pair in get_pair(value): map_rearray = calc_rearray(pair) result.setdefault(map_rearray, []).append(pair) result.setdefault(reverse_rearray(map_rearray), []).append(tuple(reversed(pair))) return result def pow_range(digit): return int((10 ** (digit // 2)) * ((10 ** 0.5) ** (digit % 2))) def num_power(digit): return list(map(lambda x: str(x ** 2), range(pow_range(digit - 1), pow_range(digit) + 1))) def num_rearray(digit): result = [] for n in range(3, digit + 1): result.append(word_rearray(num_power(n))) return result print(sorted(word_rearray(get_file('../resource/words.txt')), key=lambda x: len(x))) #print(num_rearray(9))