https://github.com/Matthias-Merzenich/stator-optimizer
This script was inspired by, and meant to be a much faster and more memory-efficient replacement for, Jeremy Dover's OR-Tools-based stator optimizer. I think I've recreated all of the features while simplifying the input.
The script takes as as input a file containing a pattern in RLE (.rle), macrocell(.mc) or rotor descriptor format and the number of ticks to advance the pattern in order to identify the rotor and stator. The script will automatically detect the input format. If the input uses a history rule, you can use the extra cell states to force particular stator cells to be on or off in the solution as follows:
Code: Select all
------------------------------------------------
history state | input state | solution state
---------------+-------------+------------------
0 (black) | off | either on or off
1 (green) | on | either on or off
2 (blue) | off | off
3 (white) | on | off
4 (red) | off | on
5 (yellow) | on | on
6 (gray) | off | either on or offThe `-a` option expands the search box. By default, the search box is the original bounding box. If the input pattern is a history pattern, all non-zero states (excluding state 6) will be used to determine the initial bounding box. The `-a` option takes four integers as input representing the amount to extend the search box to the left, right, top, and bottom respectively. Negative values contract the search box.
The option `-b any` tells the optimizer not to check the CA rules at the search boundary (i.e., the boundary cells can be anything). If a search run with `-b any` gives a valid solution, then it's proven to be minimal regardless of bounding box. By "valid" solution, I mean one that is actually stable. If the search bounds are too close to the rotor, then the optimizer can find solutions that intersect the boundary where the CA rules aren't checked, which can result in "stators" that aren't actually stable. If this happens, just increase the search box with the `-a` option and try repeat until you get a valid stator.
There are some other options which are described in the repository's readme.
One issue is that if the input is a rotor descriptor, the script requires lifelib 2.5.9 or higher, but the version on PyPI (i.e., the one pip installs) is version 2.5.6. If you give a rotor descriptor as input, the script will check your lifelib installation, and if it's too low it will use git to automatically clone the latest version to your current working directory and use that. Subsequent runs from the same directory will continue to use the cloned version. If you don't have git (and for some reason don't want to get it), you can also just download the lifelib repository from GitLab and place it into the stator-optimizer folder.
Many thanks again to Jeremy Dover for the idea and original implementation.