jonadsimon / wonder-words-generator

Generates WonderWords puzzles
Apache License 2.0
2 stars 0 forks source link

Replace the MiniZinc pre-run optimizer with an internal optimizer that operates within word-length classes #45

Closed jonadsimon closed 2 years ago

jonadsimon commented 2 years ago

Relying on the Minizinc optimizer for this preprocessing step is slow and wasteful since it can be just as easily accomplished by using a bubble-sort kind of approach within the largest word-length class which is present in the dataset.

Pseudocode:

for word in words_present:
  if len(word) < max(len(word) for word in words_present:)
    continue
  overlappability = get_overlappability(words_present)
  for word_new in words_absent:
    if len(word_new) != len(word):
      continue
    words_present_new = [w if w != word else word_new for w in words_present_new]
    overlappability_new = get_overlappability(words_present)
    if overlappability_new > overlappability:
      <hash the state for future checking>
      words_present = words_present_new
  <continue looping until full pass through list with no updates OR loop detected OR time limit reached>

Note: can't use code as-is because requires mutating words_present in-place. Will need to replace with while-loop logic. Should also use an additional out-loop to do the sweep. Also need to keep track of whether state has been visited before by e.g. hashing a sorted/concatenated version of the list.

jonadsimon commented 2 years ago

Added in https://github.com/jonadsimon/wonder-words-generator/commit/f4ad0a40111eb84fdabebc2dc6b7b3c32cdc7499

It's MUCH faster than the Minizinc version Only needs ~10 passes over the words to complete, takes a fraction of a second Easy to specify ordered constraints prioritizing optimizing the min over the optimizing the mean, but still considering both

Turned out no hashing was needed because sequence of updates induce a strict ordering on the states, so no revisiting is possible