Advertisement
avisrivastava254084

Untitled

Oct 25th, 2019
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.11 KB | None | 0 0
  1. #!/usr/bin/env python
  2. import collections
  3. import sys
  4. def find_word_squares(words):
  5.     # Preprocess words: O(#words * word-length) time and space
  6.     words_by_letter_position = collections.defaultdict(set)
  7.     for word in words:
  8.         for index, letter in enumerate(word):
  9.             words_by_letter_position[(index,letter)].add(word)
  10.     # For each word, see if we can make a square.  O(#words * word-length^2/2)
  11.     # for speed, assuming that set intersection is ~O(1) for small sets.
  12.     # Worst-case storage is O(#words * word-length) for very very contrived
  13.     # 'words'.  Normal English words will result in much smaller storage demand;
  14.     # there is a practical maximum of ~170,000 English words.
  15.     for word in words:
  16.         # Initialize a set of incomplete possible squares; each item is an N-tuple
  17.         # of words that are valid but incomplete word squares.  We could also do
  18.         # depth-first via recursion/generators, but this approach is a little
  19.         # simpler to read top-to-bottom.
  20.         possible_squares = set([(word,)])
  21.     # As long as we have any incomplete squares:
  22.     while possible_squares:
  23.         square = possible_squares.pop()
  24.         # When matching an incomplete square with N words already present,
  25.         # we need to match any prospective words to the tuples formed by
  26.         # (N, Nth character in word 0), (N, Nth character in word 1), ...
  27.         # Only words which satisfy all of those restrictions can be added.
  28.         keys = [(i, square[i][len(square)]) for i in xrange(len(square))]
  29.         possible_matches = [words_by_letter_position[key] for key in keys]
  30.         for valid_word in set.intersection(*possible_matches):
  31.             valid_square = square + (valid_word,)
  32.             # Save valid square in 'ret' if it's complete, or save it as
  33.             # a work-to-do item if it's not.
  34.             if len(valid_square) == len(word):
  35.                 yield valid_square
  36.             else:
  37.                 possible_squares.add(valid_square)
  38. if __name__ == '__main__':
  39.     for square in find_word_squares(sys.argv[1:]):
  40.         print '
  41. '.join(square)
  42.         print
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement