## apgsearch on Diagonal Symmetries

### apgsearch on Diagonal Symmetries

I just got apgsearch (after a long, long absence from here…!) and I want to change two things: size of soups searched (to something like 20*20 or 24*24) and symmetry of soup (to diagonally symmetric, hence the name). My searching on the forum threads turned up nothing. Did I miss something or what should I do to the script?

Princess of Science, Parcly Taxel

### Re: apgsearch on Diagonal Symmetries

What you should do is make adjustments to the hashsoup function at the very top of the script, primarily the part with all the "thesoup.append(...)" s. Most symmetries should be easy to handle if you know what you're doing, but I could post an example later if needed. As far as custom soup dimensions, I usually don't change them, but you really don't have to unless you have something very specific in mind, the results from 16x16 soups are interesting enough as they are.

### Re: apgsearch on Diagonal Symmetries

You would need a different hashing algorithm for a larger soup, since SHA-256 produces (yes, you guessed it) 256-bit digests. But yes, hashsoup() is where the soup-generating procedure is contained.

What do you do with ill crystallographers? Take them to the

**!***mono*-clinic### Re: apgsearch on Diagonal Symmetries

Here's a version of hashsoup() which creates soups with diagonal symmetry. Filling a 22x22 grid uses 253 of the 256 random bits available from the SHA256 hash. I've used a different method to that used by flipper77 in the main apgsearch thread. The pattern is returned instead of directly placed in the universe so that the save_soup() function can use it to correctly save the temporary rle files.
Here are the changes to the rest of the program to use it (sorry, I don't have diff tool available):

Code: Select all

```
# Constructs a 22 x 22 random soup with diagonal symmetry based on a
# SHA-256 cryptographic hash.
def hashsoupdiag(instring):
s = hashlib.sha256(instring).digest()
thesoup = []
idx = 0
for j in xrange(22):
for k in xrange(j+1):
q, r = divmod(idx, 8)
if not r:
t = ord(s[q])
if (t & (1 << (7 - r))):
thesoup.append(k)
thesoup.append(j)
if not (j == k):
thesoup.append(j)
thesoup.append(k)
idx += 1
return thesoup
```

Code: Select all

```
# Generate the soup from the SHA-256 of the concatenation of the
# seed with the index:
- hashsoup(root + str(pos + i))
+ thesoup = hashsoupdiag(root + str(pos + i))
+ g.putcells(thesoup, -11, -11)
...
results += "@ROOT "+root+"\n"
results += "@RULE "+self.rg.alphanumeric+"\n"
+ results += "@SOUP hashsoupdiag"
results += "@NUM_SOUPS "+str(numsoups)+"\n"
results += "@NUM_OBJECTS "+str(totobjs)+"\n"
...
# SHA-256 soups are 16-by-16:
- rledata = "x = 16, y = 16, rule = " + self.rg.slashed + "\n"
- hashdigest = souphash.digest()
- for j in xrange(32):
- t = ord(hashdigest[j])
- for k in xrange(8):
- if (t & (1 << (7 - k))):
- rledata += "o"
- else:
- rledata += "b"
- if ((j % 2) == 1):
- rledata += "$\n"
- rledata += "!\n"
+ thesoup = hashsoupdiag(root + str(soupnum))
try:
- f = open(rlepath, 'w')
- f.write(rledata)
- f.close()
+ g.store(thesoup, rlepath)
except:
g.warn("Unable to create soup pattern:\n" + rlepath)
...
results = "<html>\n<title>Census results</title>\n<body bgcolor=\"#FFFFCE\">\n"
+ results += "<p>Soup search conducted in " + self.rg.slashed + " with hashsoupdiag() soup generation.\n"
results += "<p>Census results after processing " + str(numsoups) + " soups (seed = " + root + "):\n"
```

The latest version of the 5S Project contains over 226,000 spaceships. There is also a GitHub mirror of the collection. Tabulated pages up to period 160 (out of date) are available on the LifeWiki.

### Re: apgsearch on Diagonal Symmetries

I happen to know Python. Without any knowledge of your script I concocted my own (this one leaves the central diag empty as it's 23 * 23):wildmyron wrote:Here's a version of hashsoup() which creates soups with diagonal symmetry…

Code: Select all

```
# \ symmetries in a 23 * 23 grid
def hashsoupdg(instring):
s = hashlib.sha256(instring).digest()
N = ord(s[0])
for k in xrange(31):
N = (N << 8) + ord(s[k + 1])
thesoup = []
for j in xrange(22):
for k in xrange(j + 1):
if N & (1 << (j * (j + 1) >> 1) + k):
thesoup.extend([j + 1, k, k, j + 1])
g.putcells(thesoup, -11, -11)
```

I obtained an eater plug after just running 20000 soups with seed HH (93 soups/s – I use a laptop). Nevertheless, good program!

Princess of Science, Parcly Taxel