Code: Select all
$ python lls -c -b 16 6 -s p3 x0 y1
Traceback (most recent call last):
File "lls", line 7, in <module>
import src.search_patterns
ImportError: No module named src.search_patterns
Code: Select all
$ python lls -c -b 16 6 -s p3 x0 y1
Traceback (most recent call last):
File "lls", line 7, in <module>
import src.search_patterns
ImportError: No module named src.search_patterns
Since you were able to run the main script with "python lls", the script lls must be in the current directory. Check whether there is a subdirectory 'src' and a file 'src/search_patterns.py' there. If not, probably the files were not unpacked completely.muzik wrote: ↑March 25th, 2024, 7:08 amCode: Select all
$ python lls -c -b 16 6 -s p3 x0 y1 Traceback (most recent call last): File "lls", line 7, in <module> import src.search_patterns ImportError: No module named src.search_patterns
Affirmative. I've also tested the other two example commands; the second (for Brain) gives the same error as the first. The third reports that ".python" is not a valid command, so I'm not sure if there's a typo at the wiki or if the python installation I'm using is somehow at fault.confocaloid wrote: ↑March 25th, 2024, 7:16 amCheck whether there is a subdirectory 'src' and a file 'src/search_patterns.py' there.
Code: Select all
# python3 lls -c -b 16 6 -s p3 x0 y1This did the trick. However, the second command on the page returns dart instead, which I don't think is right:confocaloid wrote: ↑March 25th, 2024, 7:32 amNot sure about the cause of the first error. On my system I have "python3" for Python 3, and the modified invocation (python -> python3) workedCode: Select all
# python3 lls -c -b 16 6 -s p3 x0 y1
Code: Select all
$ python3 lls -c -b 17 12 -s p3 x0 y1 -s "D2|"
Getting search pattern...
Done
Preprocessing...
Done
Width: 19
Height: 14
Duration: 4
Number of undetermined cells: 315
Number of variables: 424
Number of clauses: 43364
x = 19, y = 14, rule = B3/S23
bbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbbbbbbbbbb$
bbbooboboboboboobbb$
bbobbbooobooobbbobb$
bbbobooboboboobobbb$
bbbboboobbboobobbbb$
bbbbbbbobbbobbbbbbb$
bbbbbbbbbbbbbbbbbbb$
bbbbbbbobbbobbbbbbb$
bbbbbbbbooobbbbbbbb$
bbbbbbbbooobbbbbbbb$
bbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbbbbbbbbbb!
Total solver time: 6.353018522262573IIRC LLS traverses search space in different order on different invocations, and also depending on which SAT solver is used behind the scenes. If both spaceships are small enough to be solutions, either of them may be returned.
Code: Select all
# python3 lls -c -b 17 12 -s p3 x0 y1 -s "D2|" -nCode: Select all
#C found using LLS/kissat with:
#C python3 lls -c -b 17 12 -s p3 x0 y1 -s "D2|" -p "=62"
#C Total solver time: 140.29749941825867
x = 19, y = 14, rule = B3/S23
bbbbbbbbbbbbbbbbbbb$
bbbbbbbooboobbbbbbb$
booobobbbbbbbobooob$
bbbbbbbbobobbbbbbbb$
bbbobbobobobobbobbb$
bbbooboboboboboobbb$
bbbbbbobobobobbbbbb$
bbbbbobbobobbobbbbb$
bobobbbooboobbbobob$
bobbboobbbbboobbbob$
bbooboobbbbbooboobb$
bboobbbbbbbbbbboobb$
bbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbbbbbbbbbb!
Code: Select all
#C found using LLS/kissat with:
#C python3 lls -c -b 17 12 -s p3 x0 y1 -s "D2|" -p "<35"
#C Total solver time: 309.99119544029236
x = 19, y = 14, rule = B3/S23
bbbbbbbbbbbbbbbbbbb$
bbbobooboboboobobbb$
bbobbbbbobobbbbbobb$
bbboobbbobobbboobbb$
bbbbobbbobobbbobbbb$
bbbbbboobbboobbbbbb$
bbbbbbbbbbbbbbbbbbb$
bbbbbbbbooobbbbbbbb$
bbbbbbbobbbobbbbbbb$
bbbbbbbbobobbbbbbbb$
bbbbbbbbbobbbbbbbbb$
bbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbbbbbbbbbb!
Code: Select all
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * *
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0
1 1 0 1 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 0 0 1 1 0 1
1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1
0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1
1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1
1 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0
1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0
0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1
0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1
1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 1
0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1
0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 1 0 0 1 0 0 0 0
1 0 0 0 1 1 1 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 1 0 1
1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 1 0
0 0 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 1 1 0 1 1 1 0 0
0 0 1 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1
1 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0
1 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0
1 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0
0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
Code: Select all
python3 lls in.txt -p "<243"
Getting search pattern...
Done
Preprocessing...
Done
Width: 27
Height: 27
Duration: 2
Number of undetermined cells: 625
Number of variables: 6338
Number of clauses: 247086
x = 27, y = 27, rule = B3/S23
bbbbbbbbbbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbbobbboobbobbobbbb$
bbbboobboobbbbbbbbboobobbbb$
bbobbbbbbbboobobboobbbbobob$
bboboobbbbobbbbbbobbboooobb$
bobobbbobbbobbobbobobbbbbob$
bbobboobbbooobbbbbboooobbob$
bbbobbbbbboobobbbbobobobobb$
booobbobbobbbbbbbobbbboobob$
bbobobobooboobbbbbooobbbbbb$
bbbbbooooobbbobooooobbbbobb$
bbooobobbbobobbbobobobbooob$
bbbobbbobboooobobbbbbbboobb$
boobooobboobobbbobbbboobbbb$
bbbbboobobbobboobobobbbooob$
bobooboobbbboobobbbboobbobb$
bboobobboobbbboboboboobobob$
bbobbbbbbooobobbbbobboobbob$
bbobobbbbobbbboboooobbbbbbb$
bbbbboobooobboobbbbbbbobobb$
bbobbobbbbooobbobbbooobbbob$
bobboobbbobbooooobbbooobobb$
bbooobboobbbboboobbobobobbb$
boobobbbbbobbbbbooooooobobb$
bobooobbobobobbobbobbbobbbb$
bbbbbobbboobobbbobobobbbbbb$
bbbbbbbbbbbbbbbbbbbbbbbbbbb!
Code: Select all
bbbbbbbbbbbbbbbbbbbbbbbbbbb$
bbbbbbbbbbobbbboobbbobbbbbb$
bobbbbbbbbbobbbbbbbooboobbb$
bbobobbbobbobobbobobbbbobbb$
booobbbbobobobbbbobbbooooob$
bbbbobbooobbobbbbobobbbbbob$
bobbbbboobbbobobbbboooobbob$
boboobbooobbbbbbbbobobobobb$
booboobbobbbbbbbbobbbboobob$
bbobbbbbbbbobbbbbbooobbbbbb$
bbbbobobbbbobooboboobbbbobb$
bboobbbbobooobbboobbbobooob$
bbbobbbbbbbbooboobbbbboobob$
boooooboooboobbbbbbbbbobbob$
bbbbbbbbbboobboobbbbbbbbobb$
bboobbbbbbbbboobbbobbobbobb$
bbbbobobbooobbobbooooobbbbb$
boobbbooboobbbobbobboobooob$
bbooboboobbobboboboobbbbbbb$
bobbbboboboboobbbbbobobboob$
bbbobbobobbbobboobbooobbbbb$
bobobbbbooooobbbboboboobbob$
booooobobbboobobooobooboobb$
booobbbbbbbbbbboobbooboobbb$
bbboooboobobbbbobboobbbobbb$
bobbbooooobobbbbbooobbbbbbb$
bbbbbbbbbbbbbbbbbbbbbbbbbbb!
Code: Select all
x = 27, y = 26, rule = LifeHistory
19.3A$10.3A2.3A.5A$9.3A5.4A$.2A.A5.A.2A2.2A4.2A.A$.A.A8.A6.A5.AC$2.3A
.A6.A8.4A$CA.4A2.A8.A.A3.2A$.A2.2A.3A7.A2.A.3A$.2A.A7.A7.A2.2A$2.A10.
A.2A6.3A$2.3A5.A7.A6.A$.A5.A5.A.3A3.A3.AC$2.3A3.2A6.A5.A2.A$.A6.4A2.
2A7.3A$3.A5.A2.2A3.2A2.A$.A3.5A.A2.2A.A5.A.A$.2A.A8.2A.A4.2A.A$3.A.A
5.2A.2A.3A.3A$3.4A.A3.3A.2A3.A$8.A7.A2.A4.2A$.A3.2A.3A12.2A$C7.2A2.2A
10.A$.A5.2A2.A2.A$.A.A.A4.A4.A6.2A$5.A3.2A6.A.A$6.3C9.C!Code: Select all
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 * * * * * * * * * * * * * * * * * * * * * * * * * 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
* * * * * * * * * * * * * * * * * * * * * * * * * * *
* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 *
* 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 0 *
* 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 *
* 1 1 0 1 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 0 0 1 1 0 1 *
* 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 *
* 0 1 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 *
* 1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 *
* 1 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0 *
* 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 *
* 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1 *
* 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 *
* 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 1 *
* 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 *
* 1 0 0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 1 *
* 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 1 0 0 1 0 0 0 0 *
* 1 0 0 0 1 1 1 1 1 0 1 0 0 1 1 0 1 0 0 0 0 0 1 0 1 *
* 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 1 0 *
* 0 0 1 0 1 0 0 0 0 0 1 1 0 1 1 0 1 1 1 0 1 1 1 0 0 *
* 0 0 1 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 0 0 1 0 0 0 0 *
* 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 *
* 1 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 *
* 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 *
* 1 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 *
* 1 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 *
* 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 *
* * * * * * * * * * * * * * * * * * * * * * * * * * *Code: Select all
0 0 0 0 0 0
0 0 1 1 0 0
0 0 0 1 1 0
0 0 0 0 0 0
Code: Select all
0 0 0 0 0 0
0 0 1 1 0 0
0 0 0 1 0 0
0 0 0 1 0 0
Right, so for that search you could just do
Code: Select all
* * * * * *
* * * * * *
* * * * * *
* * * * * *
0 0 0 0 0 0
0 0 1 1 0 0
0 0 0 1 1 0
0 0 0 0 0 0Code: Select all
0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,*,*,*,*,*,*,*,*,*,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,1,1,1,1,1,0,0,0,0,0,0
0,0,1,0,0,0,0,1,0,0,0,0,0
0,0,1,0,0,0,0,0,0,0,0,0,0
0,0,0,1,0,0,0,1,0,0,0,0,0
0,0,0,0,0,1,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,1,1,1,0,0
0,0,0,0,0,0,1,1,0,1,1,0,0
0,0,0,0,0,1,0,0,0,0,1,0,0
0,0,0,0,1,1,0,1,0,1,0,0,0
0,0,0,1,1,0,0,1,0,1,0,0,0
0,0,0,0,1,1,0,0,0,0,0,0,0
0,0,0,0,0,0,0,1,1,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0Code: Select all
AssertionError: Search pattern is not cuboidalCode: Select all
x = 32, y = 32, rule = B3aijkr5j/S2aek3-acy4iz6c
8b3o$7bo2bo$7bo2bo$7b3o4$28b3o$28bo2bo$28bo2bo$29b3o11$3o$o2bo$o2bo$b
3o4$22b3o$21bo2bo$21bo2bo$21b3o!
How are you running LLS with that pattern?TigerCub414 wrote: ↑January 20th, 2025, 4:52 pmI have encountered a problem with LLS. Running it with this search pattern [...][...] results in an error -idk, the search pattern looks cuboidal to me. How can I fix the search pattern so that LLS works?Code: Select all
AssertionError: Search pattern is not cuboidal
./lls post202057.txt wrote:Code: Select all
Getting search pattern... Done Preprocessing... Done Width: 15 Height: 18 Duration: 2 Number of undetermined cells: 108 Number of variables: 108 Number of clauses: 7112 x = 15, y = 18, rule = B3/S23 bbbbbbbbbbbbbbb$ bbbbbbbbbbbbbbb$ bbbbbbbbbbbbbbb$ bbbooboobbbobbb$ bbboobbobbbbbbb$ bbbbbooobbbbbbb$ bbbboooooobbbbb$ bbbbobbbbbbobbb$ bbboobbbooobbbb$ bbboobobbbobbbb$ bbbbobbobbbobbb$ bbbobobbbobobbb$ bbbbbobbobbbbbb$ bbbbbbooobobbbb$ bbbbobbboobbbbb$ bbbbbbbbbbbbbbb$ bbbbbbbbbbbbbbb$ bbbbbbbbbbbbbbb! Total solver time: 0.05301833152770996
Code: Select all
x = 32, y = 32, rule = B3aijkr5j/S2aek3-acy4iz6c
8b3o$7bo2bo$7bo2bo$7b3o4$28b3o$28bo2bo$28bo2bo$29b3o11$3o$o2bo$o2bo$b
3o4$22b3o$21bo2bo$21bo2bo$21b3o!
Based on that, "p1 RO1" should mean "rotates by 90 degrees every generation." Yet that option isn't recognized, and instead triggers the assert on line 271 of lls. Is there a reason for this?"p2 RE\ x1" imposes the glide-reflect symmetry of a glider.
Code: Select all
import re
import sys
# get the nth (0-indexed) curly brace array from the given line
def get_array(line, n):
return eval('[' + re.findall(r"\{(.*?)\}", line)[n] + ']')
cell_rows = []
subperiod_array = []
# Read the JLS save file and extract important info
with open(sys.argv[1], 'r') as file:
for line in file:
# Get width, height, and depth
if line.startswith("columns=") or line.startswith("rows=") or line.startswith("generations="):
exec(line)
# Element 0 of subperiods is the same as generations, and elements 1 through 6 are the subperiods
if line.startswith("periods="):
subperiods = get_array(line,0)
# Get the cell array as a big list of rows. We'll organize this later.
if line.startswith("cells"):
cell_rows.append(get_array(line,1))
# To get the subperiod settings for each cell, we must reduce every entry in the "stacks" array mod 8.
if line.startswith("stacks"):
subperiod_array.append(list(map(lambda x: x % 8, get_array(line,1))))
# Lines after "[Search]" represent the search state. We only want the initial setup.
if line.startswith("[Search]"):
break
cell_array = []
# Convert our list of cell rows into a 3D array
for gen in range(generations):
cell_array.append(cell_rows[gen*rows:(gen+1)*rows])
# Create the LLS input file text
lls_input = ""
for gen in range(generations):
for row in range(rows):
for column in range(columns):
the_cell = cell_array[gen][row][column]
if the_cell == 0:
lls_input += "0,"
elif the_cell == 1:
lls_input += "1,"
elif the_cell == 2:
if subperiod_array[row][column]:
lls_input += "x" + str(gen % subperiods[subperiod_array[row][column]]) + "-" + str(row) + "-" + str(column) + ","
elif gen == 0:
lls_input += "x0" + "-" + str(row) + "-" + str(column) + ","
else:
lls_input += "*,"
else:
lls_input += "*',"
lls_input += "\n"
if gen == 0:
first_gen = lls_input
lls_input += "\n"
lls_input += first_gen
print(lls_input)
Code: Select all
python3 jls-to-lls.py jls-save-file.jdf > lls-input-file.txtCode: Select all
# jls-to-lls.py version 1.0 by Matthias Merzenich
# This is a script for converting JLS save files into LLS input files.
#
# Usage: python3 jls-to-lls.py [JLS-save-file-name] > [LLS-input-file-name]
#
# This version only supports oscillator searches. Since there are no LLS
# cell states precisely corresponding to JLS UNCHECKED or UNSET cells, this
# script uses the following conventions:
# - UNCHECKED cells do not obey subperiodicity but do obey the CA rules.
# - UNSET cells do obey subperiodicity but do not obey the CA rules.
# - UNCHECKED_FROZEN cells behave identically to FROZEN cells (i.e, they
# match the cell state in the same position in the previous generation).
import re
import sys
# There is almost never a need for six different subperiods, so the sixth
# subperiod is used to indicate that all cells at that position do not need
# to obey the CA rules. This can be useful when there are intentional errors
# in your initial setup. To turn this feature off and have subperiod six be
# treated as a normal subperiod, set subperiod_six_no_rule to False.
subperiod_six_no_rule = True
# JLS cell states
OFF = 0
ON = 1
EMPTY = 2
UNCHECKED = 6 # 'X'
UNSET = 10 # '#' Obtained in JLS by selecting a cell and pressing 'U'.
FROZEN = 18 # 'F'
UNCHECKED_FROZEN = 22 # Obtained in JLS by selecting a frozen cell and pressing 'O'.
cell_rows = []
cell_array = []
subperiod_array = []
# get the nth (0-indexed) curly brace array from the given line
def get_array(line, n):
return eval('[' + re.findall(r"\{(.*?)\}", line)[n] + ']')
# Read the JLS save file and extract important info
with open(sys.argv[1], 'r') as file:
for line in file:
# Get width, height, and depth
if line.startswith("columns=") or line.startswith("rows=") or line.startswith("generations="):
exec(line)
# Element 0 of subperiods is the full period (same as generations), and elements 1 through 6 are the subperiods
if line.startswith("periods="):
subperiods = get_array(line,0)
# Get the cell array as a big list of row arrays. We'll organize this later.
if line.startswith("cells"):
cell_rows.append(get_array(line,1))
# To get the subperiod settings for each cell, we must reduce every entry in the "stacks" array mod 8.
if line.startswith("stacks"):
subperiod_array.append(list(map(lambda x: x % 8, get_array(line,1))))
# Lines after "[Search]" represent the search state. We only want the initial setup.
if line.startswith("[Search]"):
break
# Convert our list of cell rows into a 3D array
for gen in range(generations):
cell_array.append(cell_rows[gen*rows:(gen+1)*rows])
# Set the sixth subperiod to be the full period when using
# it to identify cells that do not need to obey the CA rules
if subperiod_six_no_rule:
subperiods[6] = generations
# For each cell in cell_array, set the corresponding variable name in lls_array
lls_array = [[[0 for k in range(columns)] for j in range(rows)] for i in range(generations)]
for gen in range(generations):
for row in range(rows):
for column in range(columns):
the_cell = cell_array[gen][row][column]
if the_cell == OFF:
lls_array[gen][row][column] = "0"
elif the_cell == ON:
lls_array[gen][row][column] = "1"
elif gen == 0 or the_cell == EMPTY or the_cell == UNCHECKED or the_cell == UNSET:
lls_array[gen][row][column] = "x" + str(gen % subperiods[subperiod_array[row][column]]) + "-" + str(row) + "-" + str(column)
elif the_cell == FROZEN or the_cell == UNCHECKED_FROZEN:
lls_array[gen][row][column] = lls_array[gen - 1][row][column]
# Special suffix so that unchecked cells don't have to have to obey subperiodicity
if the_cell == UNCHECKED:
lls_array[gen][row][column] += "-uc" + str(gen)
# apostrophe suffix means the cell does not need to obey the CA rules
if the_cell == UNSET or (subperiod_six_no_rule and subperiod_array[row][column] == 6):
lls_array[gen][row][column] += "'"
# We have to do a second pass of generation 0 in case it contains any frozen cells
for row in range(rows):
for column in range(columns):
the_cell = cell_array[0][row][column]
if the_cell == FROZEN or the_cell == UNCHECKED_FROZEN:
lls_array[0][row][column] = lls_array[generations - 1][row][column]
# Create the LLS input file text
lls_input = ""
for gen in range(generations):
for row in range(rows):
for column in range(columns):
lls_input += lls_array[gen][row][column] + ","
lls_input += "\n"
if gen == 0:
gen_zero = lls_input
lls_input += "\n"
lls_input += gen_zero
print(lls_input)
Code: Select all
x = 33, y = 34, rule = B3/S23
12b2o5b2o$12b2o5b2o6$bo3b2o19b2o3bo$bo3b2o7b2ob2o7b2o3bo$o2b2o6bo2b2ob
2o2bo6b2o2bo$2bo2bo3bobo9bobo3bo2bo$2bobo6bo9bo6bobo$3bo4bobo11bobo4bo
$8b2o13b2o7$8b2o13b2o$3bo4bobo11bobo4bo$2bobo6bo9bo6bobo$2bo2bo3bobo9b
obo3bo2bo$o2b2o6bo2b2ob2o2bo6b2o2bo$bo3b2o7b2ob2o7b2o3bo$bo3b2o19b2o3b
o6$12b2o5b2o$12b2o5b2o!Code: Select all
python3 jls-to-lls.py p57-setup.jdf > p57-lls-input.txtCode: Select all
./lls p57-lls-input.txt -s 'D2-'As I was attempting to find a "stabilization" (idrk the term) for a p30 rake, I realized that the above script had no option for translations (Agars are still not supported) so I hope this helps anyone
Code: Select all
# jls-to-lls.py version 1.0+0.1 by Matthias Merzenich (Modified by Sylvani)
# This is a script for converting JLS save files into LLS input files.
#
# Usage: python3 jls-to-lls.py [JLS-save-file-name] > [LLS-input-file-name]
#
# This version doesn't support agar/wave searches. Since there are no LLS
# cell states precisely corresponding to JLS UNCHECKED or UNSET cells, this
# script uses the following conventions:
# - UNCHECKED cells do not obey subperiodicity but do obey the CA rules.
# - UNSET cells do obey subperiodicity but do not obey the CA rules.
# - UNCHECKED_FROZEN cells behave identically to FROZEN cells (i.e, they
# match the cell state in the same position in the previous generation).
import re
import sys
# There is almost never a need for six different subperiods, so the sixth
# subperiod is used to indicate that all cells at that position do not need
# to obey the CA rules. This can be useful when there are intentional errors
# in your initial setup. To turn this feature off and have subperiod six be
# treated as a normal subperiod, set subperiod_six_no_rule to False.
subperiod_six_no_rule = True
# JLS cell states
OFF = 0
ON = 1
EMPTY = 2
UNCHECKED = 6 # 'X'
UNSET = 10 # '#' Obtained in JLS by selecting a cell and pressing 'U'.
FROZEN = 18 # 'F'
UNCHECKED_FROZEN = 22 # Obtained in JLS by selecting a frozen cell and pressing 'O'.
cell_rows = []
cell_array = []
subperiod_array = []
# get the nth (0-indexed) curly brace array from the given line
def get_array(line, n):
return eval('[' + re.findall(r"\{(.*?)\}", line)[n] + ']')
# Read the JLS save file and extract important info
with open(sys.argv[1], 'r') as file:
for line in file:
# Get width, height, and depth
if line.startswith("columns=") or line.startswith("rows=") or line.startswith("generations=") or line.startswith("tile_temporal_shift_right=") or line.startswith("tile_temporal_shift_down="):
exec(line)
# Element 0 of subperiods is the full period (same as generations), and elements 1 through 6 are the subperiods
if line.startswith("periods="):
subperiods = get_array(line,0)
# Get the cell array as a big list of row arrays. We'll organize this later.
if line.startswith("cells"):
cell_rows.append(get_array(line,1))
# To get the subperiod settings for each cell, we must reduce every entry in the "stacks" array mod 8.
if line.startswith("stacks"):
subperiod_array.append(list(map(lambda x: x % 8, get_array(line,1))))
# Lines after "[Search]" represent the search state. We only want the initial setup.
if line.startswith("[Search]"):
break
# Convert our list of cell rows into a 3D array
for gen in range(generations):
cell_array.append(cell_rows[gen*rows:(gen+1)*rows])
# Set the sixth subperiod to be the full period when using
# it to identify cells that do not need to obey the CA rules
if subperiod_six_no_rule:
subperiods[6] = generations
# For each cell in cell_array, set the corresponding variable name in lls_array
lls_array = [[[0 for k in range(columns)] for j in range(rows)] for i in range(generations + 1)]
for gen in range(generations + 1):
for row in range(rows):
for column in range(columns):
row1 = row + (tile_temporal_shift_down if gen == generations else 0)
col1 = column + (tile_temporal_shift_right if gen == generations else 0)
the_cell = cell_array[gen % generations][row][column]
if the_cell == OFF:
lls_array[gen][row1][col1] = "0"
elif the_cell == ON:
lls_array[gen][row1][col1] = "1"
elif gen == 0 or the_cell == EMPTY or the_cell == UNCHECKED or the_cell == UNSET:
lls_array[gen][row1][col1] = "x" + str(gen % subperiods[subperiod_array[row][column]]) + "-" + str(row) + "-" + str(column)
elif the_cell == FROZEN or the_cell == UNCHECKED_FROZEN:
lls_array[gen][row1][col1] = lls_array[gen - 1][row1][col1]
# Special suffix so that unchecked cells don't have to have to obey subperiodicity
if the_cell == UNCHECKED:
lls_array[gen][row1][col1] += "-uc" + str(gen % generations)
# apostrophe suffix means the cell does not need to obey the CA rules
if the_cell == UNSET or (subperiod_six_no_rule and subperiod_array[row1][col1] == 6):
lls_array[gen][row1][col1] += "'"
# We have to do a second pass of generation 0 in case it contains any frozen cells
for gen in [0, generations]:
for row in range(rows):
for column in range(columns):
the_cell = cell_array[gen % generations][row][column]
if the_cell == FROZEN or the_cell == UNCHECKED_FROZEN:
lls_array[gen][row][column] = lls_array[generations - 1][row][column]
# Create the LLS input file text
lls_input = ""
for gen in range(generations + 1):
for row in range(rows):
for column in range(columns):
lls_input += lls_array[gen][row][column] + ","
lls_input += "\n"
lls_input += "\n"
print(lls_input)Code: Select all
def format_dimacs_output(dimacs_output):
lines = dimacs_output.strip('\n').split('\n')
statuses = [line[2:] for line in lines if line[0] == 's']
variable_lines = [line[2:] for line in lines if line[0] == 'v']
if len(statuses) != 1:
raise Exception('Wrong number of status lines')
if statuses[0].startswith('UNSATISFIABLE'):
return Status.UNSAT, None
elif statuses[0].startswith('SATISFIABLE'):
solution = set(literal for line in variable_lines for literal in line.split() if literal != '0')
return Status.SAT, solution
Code: Select all
git apply jls-to-lls.patch
Great! There's still a lot of features missing from this (no support for translations, for example), and there's not really any documentation for how to set up a JLS search to be compatible with LLS. It would also be nice to pull settings from JLS and apply them automatically to the LLS search, but I'm not sure how much work that would be.
Code: Select all
diff --git a/src/sat_solvers.py b/src/sat_solvers.py
index f85634b..a78ca77 100644
--- a/src/sat_solvers.py
+++ b/src/sat_solvers.py
@@ -90,7 +90,7 @@ def use_solver(solver, dimacs_string, parameters=None, timeout=None):
def format_dimacs_output(dimacs_output):
- lines = dimacs_output.strip('\n').split('\n')
+ lines = dimacs_output.replace('\r\n', '\n').strip('\n').split('\n')
statuses = [line[2:] for line in lines if line[0] == 's']
variable_lines = [line[2:] for line in lines if line[0] == 'v']
When I tried this, it took ~17 minutes with JLS, and ~10 minutes with LLS. One thing that's not obvious is that most JLS settings, including symmetry, are not read by LLS, so they need to be set manually in the command line. In this case you would need to run
Code: Select all
lls p7-hw-2.jdf -s D2-