muzik wrote:Possible pseudosymmetry suggestion: "inflated" soups, where each cell takes up a 2x2 space.

This could be especially useful for rules which simulate margolus rules with 2x2 blocks (although I don't see much evil in searching rules without this property using this pseudosymmetry). It could possibly also be made subject to the additional symmetries and size rectangle (8x32, 4x64, 2x128) options the 1x1-cell soups face, obviously scaled up for it to make sense.

I liked this idea, and since apgsearch 1.x (or 0.54+0.x, really) is very easy to work with I implemented this. Here's a patch against apgsearch 0.54+0.32i (including all the changes in 0.54+0.31i-ab3):

`--- apgsearch-2017-8-07-v0.54+0.32i.py 2017-09-01 12:08:32.293824300 +0200`

+++ apgsearch-2017-8-07-v0.54+0.32i-ab2.py 2017-09-01 12:28:35.947669300 +0200

@@ -51,7 +51,7 @@

import urllib2

#Version "number"

-vnum = "v0.54+0.32i"

+vnum = "v0.54+0.32i-ab2"

g2_8 = True

'''#Stores whether the rule is outer-totalistic or not

@@ -169,7 +169,16 @@

else:

d = 0

- for j in xrange(32):

+ jrange = 32

+ if sym == 'AB_sha512_16x32_Test':

+ s = hashlib.sha512(instring).digest()

+ jrange = 64

+

+ if sym == 'AB_sha512_20x20_Test':

+ s = hashlib.sha512(instring).digest()

+ jrange = 50

+

+ for j in xrange(jrange):

t = ord(s[j])

@@ -195,6 +204,12 @@

x = k + 8*(j % 32)

y = int(j / 32)

+ elif (sym == 'AB_sha512_20x20_Test'):

+

+ bitno = k + 8*j

+ x = bitno % 20

+ y = int(bitno / 20)

+

else:

x = k + 8*(j % 2)

y = int(j / 2)

@@ -203,8 +218,21 @@

if ((d == 0) | (x >= y)):

- thesoup.append(x)

- thesoup.append(y)

+ if (sym == 'AB_C1_2x2_32x32_Test'):

+

+ thesoup.append(2*x)

+ thesoup.append(2*y)

+ thesoup.append(2*x+1)

+ thesoup.append(2*y)

+ thesoup.append(2*x)

+ thesoup.append(2*y+1)

+ thesoup.append(2*x+1)

+ thesoup.append(2*y+1)

+

+ else:

+

+ thesoup.append(x)

+ thesoup.append(y)

if (sym == '32x32'):

@@ -296,10 +324,54 @@

thesoup.append(thesoup[x+1])

thesoup.append(-thesoup[x]-1)

+ if sym == "AB_256x256_Test":

+

+ thearray = [

+ [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],

+ [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]

+ ]

+

+ for j in xrange(0, len(thesoup), 2):

+ x = thesoup[j]

+ y = thesoup[j + 1]

+ thearray[x][y] = 1

+

+ thesoup = [];

+ for j in xrange(256):

+ for k in xrange(256):

+ ax = int(j / 16)

+ ay = int(k / 16)

+ bx = j % 16

+ by = k % 16

+ if (thearray[ax][ay] * thearray[bx][by]) == 1:

+ thesoup.append(j)

+ thesoup.append(k)

+

+# rlepath = g.getdir("temp") + "thesoup.rle"

+# g.store(thesoup, rlepath)

+# g.getstring("Quit now and look at the saved soup.", rlepath)

+

return thesoup

# Checks if symmetry is a valid one.

def check(string):

+ if string in ['AB_256x256_Test', 'AB_sha512_16x32_Test', 'AB_sha512_20x20_Test', 'AB_C1_2x2_32x32_Test']:

+ return string

+

symmetries = {"C1": [],

"C2": ["1", "2", "4"],

"C4": ["1", "4"],

@@ -13208,7 +13280,7 @@

if not upload:

rootstring = g.getstring("What seed to use for this search (make this unique)?", datetime.datetime.now().isoformat()+"")

rulestring = g.getstring("Which rule to use?", "B3/S23")

- symmstring = g.getstring("What symmetries to use?", "C1")

+ symmstring = g.getstring("What symmetries to use?", 'AB_C1_2x2_32x32_Test')

pseudo = False

payoshakey = g.getstring("Please enter your key (visit "+get_server_address()+"/payosha256 in your browser).", "#anon") if upload else None

if not upload:

@@ -13221,7 +13293,7 @@

orignumber = min(orignumber, 100000000)

number = orignumber

initpos = 0

- if symmstring not in ["1x256", "2x128", "4x64", "8x32", "C1", "C2_1", "C2_2", "C2_4", "C4_1", "C4_4", "D2_+1", "D2_+2", "D2_x", "D4_+1", "D4_+2", "D4_+4", "D4_x1", "D4_x4", "D8_1", "D8_4"]:

+ if symmstring not in ["AB_256x256_Test", "AB_sha512_16x32_Test", "AB_sha512_20x20_Test", "AB_C1_2x2_32x32_Test", "1x256", "2x128", "4x64", "8x32", "C1", "C2_1", "C2_2", "C2_4", "C4_1", "C4_4", "D2_+1", "D2_+2", "D2_x", "D4_+1", "D4_+2", "D4_+4", "D4_x1", "D4_x4", "D8_1", "D8_4"]:

g.exit(symmstring+" is not a valid symmetry option")

soup = Soup()

@@ -13348,6 +13420,7 @@

g.new("Symmetry test")

symmetries = [["32x32", "C1", "8x32", "4x64", "2x128", "1x256"],

+ ["AB_256x256_Test", "AB_sha512_16x32_Test", 'AB_sha512_20x20_Test', 'AB_C1_2x2_32x32_Test'],

["C2_1", "C2_2", "C2_4"],

["C4_1", "C4_4"],

["D2_+1", "D2_+2", "D2_x"],

The test symmetry I used is called "AB_C1_2x2_32x32_Test" -- a fairly horrible name, admittedly, but it tells you everything you need to know at a glance:

- The "original" soups are C1-symmetric (i.e. asymmetric);
- Each cell gets "inflated" to size 2x2;
- The resulting soup is size 32x32.

This could easily be adapted to arbitrary "inflation factors" and (pseudo-)symmetries, too.