Page 1 of 1
apgsearch on Diagonal Symmetries
Posted: December 17th, 2014, 5:16 am
by Freywa
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?
Re: apgsearch on Diagonal Symmetries
Posted: December 17th, 2014, 5:59 am
by flipper77
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
Posted: December 17th, 2014, 5:07 pm
by calcyman
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.
Re: apgsearch on Diagonal Symmetries
Posted: December 18th, 2014, 3:37 am
by wildmyron
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.
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
Here are the changes to the rest of the program to use it (sorry, I don't have diff tool available):
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"
Re: apgsearch on Diagonal Symmetries
Posted: December 18th, 2014, 4:45 am
by Freywa
wildmyron wrote:Here's a version of hashsoup() which creates soups with diagonal symmetry…
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):
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)
Then you just replace the relevant algorithm in the main loop.
I obtained an eater plug after just running 20000 soups with seed HH (93 soups/s – I use a laptop). Nevertheless, good program!