ConwayLife.com - A community for Conway's Game of Life and related cellular automata
Home  •  LifeWiki  •  Forums  •  Download Golly

Script request thread

For scripts to aid with computation or simulation in cellular automata.

Re: Script request thread

Postby KittyTac » September 27th, 2018, 8:29 am

dvgrn wrote:
Gamedziner wrote:I would like a script that searches for a glider synthesis for a given input pattern, to try to find a synthesis for Sir Robin.

So would I. Actually, I'd like a script that actually finds a synthesis, rather than just searching for it. While I'm wishing, I'd like it to be guaranteed that the synthesis is the most efficient one possible.

Reminds me of http://bash.org/?605501.

Also, even an inefficient synthesis would be fine for a Sir Robin gun. We can optimize it later, but we need the gun ASAP. Why? For science, of course!
User avatar
KittyTac
 
Posts: 532
Joined: December 21st, 2017, 9:58 am

Re: Script request thread

Postby danny » September 27th, 2018, 3:08 pm

KittyTac wrote:Also, even an inefficient synthesis would be fine for a Sir Robin gun. We can optimize it later, but we need the gun ASAP. Why? For science, of course!


All I'll say is that you are severely underestimating the difficulty of finding a glider synthesis of Sir Robin.
I prefer Dani now, but Danny is fine seeing as it's my username and I've already made 4 too many accounts.
User avatar
danny
 
Posts: 768
Joined: October 27th, 2017, 3:43 pm
Location: i love to eat bees

Re: Script request thread

Postby cordership3 » October 5th, 2018, 10:37 am

A "rule roulette" script that randomly selects transitions for an isotropic two-state rule.
All hail WADUFI our king.
User avatar
cordership3
 
Posts: 110
Joined: August 23rd, 2016, 8:53 am
Location: haha long boy

Re: Script request thread

Postby dvgrn » October 5th, 2018, 12:24 pm

cordership3 wrote:A "rule roulette" script that randomly selects transitions for an isotropic two-state rule.

How should it be different from change-random-isotropic-bit-v1.0.lua?
User avatar
dvgrn
Moderator
 
Posts: 4980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby KittyTac » October 5th, 2018, 10:33 pm

dvgrn wrote:
cordership3 wrote:A "rule roulette" script that randomly selects transitions for an isotropic two-state rule.

How should it be different from change-random-isotropic-bit-v1.0.lua?

Yeah, just click it for about 5 minutes until you get a more-or-less-random rule.
User avatar
KittyTac
 
Posts: 532
Joined: December 21st, 2017, 9:58 am

Re: Script request thread

Postby Goldtiger997 » October 6th, 2018, 1:40 am

Does anyone have a script to convert an rle to a plaintext file? It would be very useful to make input files for programs like gencols. I've been searching for a while now and the only one I found was a c program by Mark Niemiec from 1997, which I couldn't get to work.

Thanks in advance!
Things to work on:
  • Work on the snowflakes orthogonoid
User avatar
Goldtiger997
 
Posts: 460
Joined: June 21st, 2016, 8:00 am
Location: 11.329903°N 142.199305°E

Re: Script request thread

Postby chris_c » October 6th, 2018, 3:38 am

Goldtiger997 wrote:Does anyone have a script to convert an rle to a plaintext file? It would be very useful to make input files for programs like gencols. I've been searching for a while now and the only one I found was a c program by Mark Niemiec from 1997, which I couldn't get to work.

Thanks in advance!


Here's a python script that I use. I call it rle2col.py:

import sys

d = { 'b': '.', 'o': '*', '$': '!' }

reps = 0
for line in sys.stdin:
    if not "=" in line:
        for x in line:
            if x.isdigit():
                reps = 10 * reps + int(x)
            elif x in d:
                sys.stdout.write(d[x] * max(reps, 1))
                reps = 0
            elif x == "!":
                sys.stdout.write("\n")


Usage: python rle2col.py > output.col, and then paste in your RLE and exit with Ctrl+D.
chris_c
 
Posts: 862
Joined: June 28th, 2014, 7:15 am

Re: Script request thread

Postby dvgrn » October 6th, 2018, 8:56 am

chris_c wrote:
Goldtiger997 wrote:Does anyone have a script to convert an rle to a plaintext file? It would be very useful to make input files for programs like gencols.

Here's a python script that I use. I call it rle2col.py:
...
Usage: python rle2col.py > output.col, and then paste in your RLE and exit with Ctrl+D.

I usually run my Python scripts from inside Golly. Here's my version -- works on the current selection, and copies to the clipboard:

# makeASCIIforLexicon.py
import golly as g
r = g.getselrect()
s="        "
for y in range(r[3]):
  for x in range(r[2]):
    s+="*" if g.getcell(x+r[0],y+r[1]) == 1 else "."
  s+="\n        "
g.setclipstr(s)

You can get rid of the eight leading spaces if you don't need them, and/or replace the "\n" with "!" to get gencols-compatible output.
User avatar
dvgrn
Moderator
 
Posts: 4980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby wildmyron » October 8th, 2018, 1:35 am

dvgrn wrote:
cordership3 wrote:A "rule roulette" script that randomly selects transitions for an isotropic two-state rule.

How should it be different from change-random-isotropic-bit-v1.0.lua?

An earlier Python script also written by dvgrn probably matches the request better than change-random-isotropic-bit-v1.0.lua:
viewtopic.php?p=43545#p43545
wildmyron
 
Posts: 875
Joined: August 9th, 2013, 12:45 am

Re: Script request thread

Postby Scorbie » October 8th, 2018, 10:06 pm

dvgrn wrote:
chris_c wrote:
Goldtiger997 wrote:Does anyone have a script to convert an rle to a plaintext file? It would be very useful to make input files for programs like gencols.

Here's a python script that I use. I call it rle2col.py:
...
Usage: python rle2col.py > output.col, and then paste in your RLE and exit with Ctrl+D.

I usually run my Python scripts from inside Golly. Here's my version -- works on the current selection, and copies to the clipboard:
...
You can get rid of the eight leading spaces if you don't need them, and/or replace the "\n" with "!" to get gencols-compatible output.

Well, sharing pattern2ascii scripts seems to be an interesting trend, so here's mine:
import golly as g

MULTILINE = True
CR = '\n' if MULTILINE else '!'
CELL_TO_CHAR = ['.', '*']

# Get selection first
r=g.getselrect()
if len(r)==0:
    r=g.getrect()
    if len(r)==0: g.exit("No pattern, nothing to do.")
sel = g.getcells(r)
if len(sel)==0: g.exit("Nothing in selection.")

# And parse!
chars = []
for y in xrange(r[1],r[1]+r[3]):
    for x in xrange(r[0], r[0]+r[2]):
        chars.append(CELL_TO_CHAR[g.getcell(x, y)])
    chars.append(CR)
g.setclipstr(''.join(chars))
g.exit("Copied to clipboard.")

Two params are tweakable:
1. `MULTILINE = True or False` : changes the line seperator (`CR`)
2. `CELL_TO_CHAR`: useful for mapping other rules such as LifeHistory / LifeBellman etc...
Best wishes to you, Scorbie
User avatar
Scorbie
 
Posts: 1367
Joined: December 7th, 2013, 1:05 am

Re: Script request thread

Postby Sarp » October 9th, 2018, 1:26 am

Is there any script that when you give it a spaceship, it gives a rle of all possible collisions
WADUFI
Sarp
 
Posts: 79
Joined: March 1st, 2015, 1:28 pm

Re: Script request thread

Postby dvgrn » October 9th, 2018, 4:40 am

Sarp wrote:Is there any script that when you give it a spaceship, it gives a rle of all possible collisions

Depends. gencols is a powerful tool, with filtering capabilities so you get only what you're looking for -- but it would need to be recompiled for non-Life rules, and isotropic rules aren't supported.

In Golly's Scripts folder, there's a sample script -- pd-glider.lua or pd-glider.py -- that shows how to generate all possible combinations of two objects. It may be worth learning how to adjust one of those to generate collisions between two spaceships of your choice.

In either case, you have to apply your knowledge of the specific spaceship(s) to make sure that you've enumerated all possible collisions. It would take a very sophisticated script to do that analysis for you and come up with all the unique collisions without any duplicates... that would be very nice to have, but nobody has written one because it's painfully difficult.

What rulespace are you asking about? Assumptions that work for Life don't work for other Life-like rules, or isotropic rules, and then if you want to support Larger than Life the details are different again.
User avatar
dvgrn
Moderator
 
Posts: 4980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby KittyTac » October 10th, 2018, 10:25 am

Write me a script that selects an entire bounded grid and randomly fills it.
User avatar
KittyTac
 
Posts: 532
Joined: December 21st, 2017, 9:58 am

Re: Script request thread

Postby dvgrn » October 10th, 2018, 12:34 pm

KittyTac wrote:Write me a script that selects an entire bounded grid and randomly fills it.

Apple Bottom wrote:
KittyTac wrote:I can't write scripts.

Nobody was born with that ability, so your mission, should you choose to accept it, is: learn how to do it.

In this case, most of the work would be coming up with a detailed spec. What exactly does it mean, that the script "selects an entire bounded grid"? For the script to select (the contents of) a bounded grid, the bounded grid would have to exist already.

However, I'm guessing you might really mean something like
  • User makes a selection in Golly
  • User runs script
  • If there is no selection, script prints a helpful message and exits
  • Script creates a new layer (?) [maybe not, this is kind of annoying after you run the script several times]
  • Script sets rule for new layer to match current rule, altered to make a bounded grid the size of the existing selection. [Toroidal? Regular bounded plane? Sphere? User can choose what kind of bounds, maybe?]
  • Script uses g.randfill() to fill the entire bounded region with random cells. [50% filled? Random choice of states for multistate rules? Allow user to specify?]

It's hard to be sure enough of what's wanted, to actually start writing the script.

Once a detailed spec is available, the script is about four lines of Lua code, so if you can't figure out how to do it using Golly > Help > Lua Scripting, probably someone won't be able to resist helping to write it -- given a little encouragement in the form of leading questions like "I wrote these four lines, but I'm getting such-and-such mysterious error. What's going wrong?"

Sarp's and others' previous requests on this thread would also be much more likely to be completed if all the details were included.

Writing a spec like this will probably either make it clear exactly how to write the script, or it will make it clear that the request is too vague and it's actually impossible or very difficult to write the script.
User avatar
dvgrn
Moderator
 
Posts: 4980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby KittyTac » October 10th, 2018, 9:42 pm

I meant that if the current universe is a bounded grid, it selects it in its entirety and randomly seeds it.
User avatar
KittyTac
 
Posts: 532
Joined: December 21st, 2017, 9:58 am

Re: Script request thread

Postby dvgrn » October 10th, 2018, 10:38 pm

KittyTac wrote:I meant that if the current universe is a bounded grid, it selects it in its entirety and randomly seeds it.

Okay, here you go. Save this in a "MyScripts" folder or some such, and map a key to it in File > Preferences > Keyboard:

local g = golly()
w, h = g.getwidth(), g.getheight()
if w*h == 0 then g.exit("At least one dimension is not bounded.") end
g.select({-(w//2), -(h//2),w,h})
g.randfill(50)

You can definitely do this level of scripting yourself, by trial and error and looking things up in Golly Help and on Google. I do admit it can be a painful process, but that's basically what I have to do every time.
User avatar
dvgrn
Moderator
 
Posts: 4980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby wildmyron » October 11th, 2018, 12:54 am

dvgrn wrote:
KittyTac wrote:I meant that if the current universe is a bounded grid, it selects it in its entirety and randomly seeds it.

Okay, here you go. Save this in a "MyScripts" folder or some such, and map a key to it in File > Preferences > Keyboard:

local g = golly()
w, h = g.getwidth(), g.getheight()
if w*h == 0 then g.exit("At least one dimension is not bounded.") end
g.select({-(w//2), -(h//2),w,h})
g.randfill(50)

You can definitely do this level of scripting yourself, by trial and error and looking things up in Golly Help and on Google. I do admit it can be a painful process, but that's basically what I have to do every time.

It didn't take long for someone to be unable to resist. :D

For multistate rules the, Golly's randfill() can be annoying due to the inability to specify which states to fill with. One solution is to implement a custom random fill function, such as the one from apgsearch. For the case where a random fill with only M out of N states is desired I change the rule to a Generations rule ('//M'), do the fill, and then change it back again. This does have undesirable side effects if only part of the pattern is to be filled, and it changes some settings too, but most of the time they're not a problem. For this script the technique looks like this:
-- Load Golly's lua interface
local g = golly()

-- Get the width and height of a bounded universe (0 if unbounded)
w, h = g.getwidth(), g.getheight()

-- Error checking
if w*h == 0 then g.exit("At least one dimension is not bounded.") end

-- The number of states to use in the random fill (including 0), stored as a string
fillstates = '3'

-- Store the current rule
rulestr = g.getrule()

-- Change rule to Generations with the desired number of states
-- The .. operator combines two strings into one string
g.setrule('//'..fillstates)

-- Select a bounding box specified in an array: {top_left_x, top_left_y, width, height}
g.select({-(w//2), -(h//2), w, h})

-- Do the fill with a specified probability for non-zero
-- Each non-zero state has equal probability
g.randfill(50)

-- Restore the rule
g.setrule(rulestr)

-- Remove the selection using an empty array
g.select({})

dvgrn wrote:You can definitely do this level of scripting yourself, by trial and error and looking things up in Golly Help and on Google. I do admit it can be a painful process, but that's basically what I have to do every time.

In the interests of fostering this process I've added comments to each line of the script. I hope they are helpful.
wildmyron
 
Posts: 875
Joined: August 9th, 2013, 12:45 am

Re: Script request thread

Postby danny » October 27th, 2018, 7:16 pm

Someone should write an extension that checks a user's (most likely your) discoveries page every 30 minutes and reports anything new you've discovered.
I prefer Dani now, but Danny is fine seeing as it's my username and I've already made 4 too many accounts.
User avatar
danny
 
Posts: 768
Joined: October 27th, 2017, 3:43 pm
Location: i love to eat bees

Re: Script request thread

Postby Senso » November 1st, 2018, 2:35 pm

danny wrote:Someone should write an extension that checks a user's (most likely your) discoveries page every 30 minutes and reports anything new you've discovered.


I wrote a quick script that does just that and posts new discoveries of mine on a slack channel. It scrapes the /<user>/all#discoveries page and compares with a local copy. I'm not sure if it would impact the site if a lot of people scraped that rather heavy page constantly though. If it's frowned upon, I'll actually stop it.
User avatar
Senso
 
Posts: 16
Joined: November 1st, 2018, 11:36 am
Location: I call that one "shoving match"

Re: Script request thread

Postby danny » November 1st, 2018, 11:57 pm

Senso wrote:
danny wrote:Someone should write an extension that checks a user's (most likely your) discoveries page every 30 minutes and reports anything new you've discovered.


I wrote a quick script that does just that and posts new discoveries of mine on a slack channel. It scrapes the /<user>/all#discoveries page and compares with a local copy. I'm not sure if it would impact the site if a lot of people scraped that rather heavy page constantly though. If it's frowned upon, I'll actually stop it.

Ooh. Sadly I don't have slack.
I prefer Dani now, but Danny is fine seeing as it's my username and I've already made 4 too many accounts.
User avatar
danny
 
Posts: 768
Joined: October 27th, 2017, 3:43 pm
Location: i love to eat bees

Re: Script request thread

Postby Senso » November 2nd, 2018, 12:55 pm

danny wrote:Ooh. Sadly I don't have slack.


You can basically just parse the HTML page and keep a copy of the objects you've found and print the difference when it finds a new one. A REST API on Catagolue would be awesome though. ;)

A quick and dirty script that checks Catagolue every 30 minutes is below. Be mindful not to hit the site too often/too quickly, removing the sleep() call would DOS it.

import urllib2
import cPickle
import os
import re

USERNAME = 'your Catagolue username'

def parse_cata():
    try:
        url = 'https://catagolue.appspot.com/user/%s/all#discoveries' % USERNAME
        fd = urllib2.urlopen(url, timeout=10)
        data = fd.read()
    except urllib2.URLError:
        print "Couldn't connect to Catagolue"
        return

    try:
        with open('catagolue.data') as derp:
            all_finds = cPickle.load(derp)
    except:
        all_finds = {}

    pattern = re.compile('\<a href=\"\/object\/(.+)\/(.+)\"\>')

    objects = re.findall(pattern, data)
    if objects:
        for obj in objects:
            if obj not in all_finds:
                all_finds[obj] = True
                url = "https://catagolue.appspot.com/object/%s/%s" % (obj[0], obj[1])
                txt = "You found a new pattern: %s " % (url,)
                print txt

    with open('catagolue.data', 'wb') as derp:
        cPickle.dump(all_finds, derp)

if __name__ == '__main__':
    while True:
        parse_cata()
        os.sleep(1800) # sleep for 30 minutes
User avatar
Senso
 
Posts: 16
Joined: November 1st, 2018, 11:36 am
Location: I call that one "shoving match"

Re: Script request thread

Postby muzik » November 2nd, 2018, 1:15 pm

Are there any search programs that can be used to find replicators? I'm thinking something like rulesrc.
waiting for apgsearch to support one-dimensional rules
muzik
 
Posts: 2855
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: Script request thread

Postby Ian07 » November 3rd, 2018, 12:50 pm

Does anyone know of a script which can convert RLEs into Heinrich Koenig's small object format?

EDIT: Just learned that Catagolue Reloaded does this, so I'll try using that for now.

EDIT 2: Got Opera and the extension, everything else works fine but the Pentadecathlon link doesn't. :?
Ian07
 
Posts: 68
Joined: September 22nd, 2018, 8:48 am

Re: Script request thread

Postby wildmyron » November 4th, 2018, 11:30 pm

Ian07 wrote:Does anyone know of a script which can convert RLEs into Heinrich Koenig's small object format?

EDIT: Just learned that Catagolue Reloaded does this, so I'll try using that for now.

EDIT 2: Got Opera and the extension, everything else works fine but the Pentadecathlon link doesn't. :?


In case it might be useful to anyone, here is an almost complete Python implementation for Golly which I hacked up years ago. Unless there are other issues, the only thing missing is representing spaceships in the standard form according to the spec for direction traveled. It encodes the pattern in the current layer rather than converting rle and copies the sof representation of the pattern to the clipboard. If you want an rle converter it should be just a matter of inserting a few lines to place the pattern in a new layer.

# Canonical small object format representation
# Representation for CGoL objects devised by Heinrich Koenig
# Format description at http://conwaylife.com/wiki/SOF
# Further information at http://www.pentadecathlon.com/objects/definitions/definitions.php
# Determine the canonical small object format representation of the current
# pattern using the comparison rules. Special case rules for spaceships are
# not yet implemented.
#
# By Arie Paap
# Oct. 2014

import golly as g

# Obtains a canonical representation of the current pattern
# Uses algorithm by Adam P. Goucher
def sof_canonise(duration):

    sof = ""
   
    # We need to compare each phase to find the one used to determine the
    # pattern's standard form:
    for t in xrange(duration):

        if (duration > 1):
         g.run(1)
           
    rect = g.getrect()
    if (len(rect) == 0):
        return "0"

    ox = rect[0]
    oy = rect[1]
    x_length = rect[2]
    y_breadth = rect[3]
       
    # Choose the orientation which comes first according to sof comparison rules:
    sof = sof_representation(x_length, y_breadth, ox, oy, 1, 0, 0, 1)
    sof = sof_compare(sof, sof_representation(x_length, y_breadth, ox+x_length-1, oy, -1, 0, 0, 1)) # flip_x
    sof = sof_compare(sof, sof_representation(x_length, y_breadth, ox, oy+y_breadth-1, 1, 0, 0, -1)) # flip_y
    sof = sof_compare(sof, sof_representation(x_length, y_breadth, ox+x_length-1, oy+y_breadth-1, -1, 0, 0, -1)) # 180
    sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox, oy, 0, 1, 1, 0)) # swap_xy
    sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox+x_length-1, oy, 0, -1, 1, 0)) # cw 90
    sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox, oy+y_breadth-1, 0, 1, -1, 0)) # ccw 90
    sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox+x_length-1, oy+y_breadth-1, 0, -1, -1, 0)) # swap_xy_flip

    return sof

# Determine sof for current pattern in specified orientation:
def sof_representation(length, breadth, ox, oy, a, b, c, d):

    sof = ""
   
    for v in xrange(breadth):
        value = 1
        run = 0
        blank = True
        if (v != 0):
            sof += "-"
        for u in xrange(length+1):
            x = ox + a*u + b*v
            y = oy + c*u + d*v
           
            if (g.getcell(x,y) == value):
                # Continue the run
                run += 1
            else:
                # Encode the run, unless a run of zeros reaches the boundary
                if (u < length or value == 1):
                    while (run > 78):
                        run -= 78
                        sof += "~0"
                    sof += chr(run + ord('0'))
                run = 1
                value = 1 - value   # Toggle value
            if (value==1):
                blank = False
        if (blank == True):
            # Remove unnecessary '0'
            sof = sof[:-2] + '-'
    sof += "."
    return sof

# Compares two sof patterns according to sof comparison rules.
def sof_compare(a, b):
   
    alines = str.split(a, '-')
    blines = str.split(b, '-')
    aline = ''
    bline = ''
   
    # Find first line with different cell
    for line in xrange(0, len(a)):
        aline = alines[line]
        bline = blines[line]
        if not (aline == bline):
            break
   
    # Find first difference
    value = 1
    ii = 0
    for ii in xrange(0, min(len(aline), len(bline))):
        if not (aline[ii] == bline[ii]):
            break
        value = 1 - value
   
    if (value == 1):
        if int(aline[ii]) > int(bline[ii]):
            return a
        else:
            return b
    else:
        if int(aline[ii]) > int(bline[ii]):
            return b
        else:
            return a
   
    g.warn("Did not compare")
   
    return '#'

p = int(g.getstring("Enter period of pattern", "1"))
canonPatt = sof_canonise(p)
g.setclipstr(canonPatt)
g.show("SOF representation of pattern is: " + canonPatt + " (copied to clipboard).")
wildmyron
 
Posts: 875
Joined: August 9th, 2013, 12:45 am

Re: Script request thread

Postby Apple Bottom » November 5th, 2018, 4:32 am

Ian07 wrote:EDIT: Just learned that Catagolue Reloaded does this, so I'll try using that for now.

EDIT 2: Got Opera and the extension, everything else works fine but the Pentadecathlon link doesn't. :?


The extension does it, but rather poorly I'm afraid.

I originally hacked something together to be able to do the same LifeWiki work you're doing now, but after being done with the still lifes (for which it did work), the benefit of fixing it to also work for other patterns did not meet the cost of doing so. :)

Patches to the extension are welcome of course, the extension code is on Github.
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!
User avatar
Apple Bottom
 
Posts: 989
Joined: July 27th, 2015, 2:06 pm

PreviousNext

Return to Scripts

Who is online

Users browsing this forum: No registered users and 1 guest