apgsearch on Diagonal Symmetries

For scripts to aid with computation or simulation in cellular automata.
Post Reply
User avatar
Freywa
Posts: 626
Joined: June 23rd, 2011, 3:20 am
Location: Singapore
Contact:

apgsearch on Diagonal Symmetries

Post by Freywa » December 17th, 2014, 5:16 am

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

flipper77
Posts: 197
Joined: October 24th, 2010, 3:25 am
Location: Spokane, WA

Re: apgsearch on Diagonal Symmetries

Post by flipper77 » December 17th, 2014, 5:59 am

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.

User avatar
calcyman
Posts: 2127
Joined: June 1st, 2009, 4:32 pm

Re: apgsearch on Diagonal Symmetries

Post by calcyman » December 17th, 2014, 5:07 pm

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!

wildmyron
Posts: 1343
Joined: August 9th, 2013, 12:45 am

Re: apgsearch on Diagonal Symmetries

Post by wildmyron » December 18th, 2014, 3:37 am

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"
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.

User avatar
Freywa
Posts: 626
Joined: June 23rd, 2011, 3:20 am
Location: Singapore
Contact:

Re: apgsearch on Diagonal Symmetries

Post by Freywa » December 18th, 2014, 4:45 am

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!
Princess of Science, Parcly Taxel

Post Reply