Page 21 of 26

Re: Script request thread

Posted: July 23rd, 2022, 3:00 am
by atavoidirc
Apgcode-to-rle that works on multistate apgcodes.

Re: Script request thread

Posted: July 23rd, 2022, 3:13 am
by carsoncheng
atavoidirc wrote: July 23rd, 2022, 3:00 am Apgcode-to-rle that works on multistate apgcodes.
Here is an example script using lifelib:

Code: Select all

import lifelib
sess = lifelib.load_rules('g3b2s')
lt = sess.lifetree()
apgcode = "xq4_3482h8a_03482lx8"
pat = lt.pattern(apgcode)
rle = pat.rle_string()
print(rle)
Note that in a lifetree, a pattern can be formed from an apgcode as well, other than an RLE. Modify the rule and the apgcode according to your own needs.

A solution for Golly is actually at the very beginning of this thread. However, it should be modified as the Golly script mentioned copies the RLE onto the clipboard, whereas you probably want it stored in a variable.

Re: Script request thread

Posted: July 23rd, 2022, 3:40 am
by atavoidirc
carsoncheng wrote: July 23rd, 2022, 3:13 am
atavoidirc wrote: July 23rd, 2022, 3:00 am Apgcode-to-rle that works on multistate apgcodes.
Here is an example script using lifelib:

Code: Select all

import lifelib
sess = lifelib.load_rules('g3b2s')
lt = sess.lifetree()
apgcode = "xq4_3482h8a_03482lx8"
pat = lt.pattern(apgcode)
rle = pat.rle_string()
print(rle)
Note that in a lifetree, a pattern can be formed from an apgcode as well, other than an RLE. Modify the rule and the apgcode according to your own needs.

A solution for Golly is actually at the very beginning of this thread. However, it should be modified as the Golly script mentioned copies the RLE onto the clipboard, whereas you probably want it stored in a variable.
1. Is the script a golly script?
2.The apgcode-to-rle fails if there's more than 2 states.

Re: Script request thread

Posted: July 23rd, 2022, 4:36 am
by carsoncheng
atavoidirc wrote: July 23rd, 2022, 3:40 am
carsoncheng wrote: July 23rd, 2022, 3:13 am
atavoidirc wrote: July 23rd, 2022, 3:00 am Apgcode-to-rle that works on multistate apgcodes.
Here is an example script using lifelib:

Code: Select all

import lifelib
sess = lifelib.load_rules('g3b2s')
lt = sess.lifetree()
apgcode = "xq4_3482h8a_03482lx8"
pat = lt.pattern(apgcode)
rle = pat.rle_string()
print(rle)
Note that in a lifetree, a pattern can be formed from an apgcode as well, other than an RLE. Modify the rule and the apgcode according to your own needs.

A solution for Golly is actually at the very beginning of this thread. However, it should be modified as the Golly script mentioned copies the RLE onto the clipboard, whereas you probably want it stored in a variable.
1. Is the script a golly script?
2.The apgcode-to-rle fails if there's more than 2 states.
I don't know of any Golly scripts that can convert an apgcode in such rules to an RLE. I am posting the lifelib solution because I thought you might be writing a lifelib script. However, the lifelib script above works for all rules, as far as I know. Therefore, I suggest rewriting your script with lifelib if you would like to.

Re: Script request thread

Posted: July 29th, 2022, 5:03 am
by confocaloid
toroidalet wrote: January 19th, 2021, 6:00 pm Here's a useful script for this sort of thing. You give it a pattern and it will find all rules where it behaves exactly like the original rule for a given number of generations (this version doesn't use minus signs).
Here is a modified script from here that should hopefully work with Python 3.

Code: Select all

# Rule computation script for use with Golly.
# Author: Nathaniel Johnston (nathaniel@nathanieljohnston.com), June 2009.
# Updated by: Peter, NASZVADI (), June 2017.

# Gives the maximal family of rules that a still life, oscillator, or spaceship
# works under. Must be called while the rule is set of one such family
# For example, to find out what rules a glider works in, first set the rule
# to Life or HighLife, not Seeds.
# Handles nontotalistic rules, too, so it needs Golly 2.8 or newer.

import golly as g
from glife import validint
# from string import replace

def replace(s, old, new, count = None):
   if count is None:
      return s.replace(old, new)
   return s.replace(old, new, count)

Hensel = [
    ['0'],
    ['1c', '1e'],
    ['2a', '2c', '2e', '2i', '2k', '2n'],
    ['3a', '3c', '3e', '3i', '3j', '3k', '3n', '3q', '3r', '3y'],
    ['4a', '4c', '4e', '4i', '4j', '4k', '4n', '4q', '4r', '4t', '4w', '4y', '4z'],
    ['5a', '5c', '5e', '5i', '5j', '5k', '5n', '5q', '5r', '5y'],
    ['6a', '6c', '6e', '6i', '6k', '6n'],
    ['7c', '7e'],
    ['8']
]

# Python versions < 2.4 don't have "sorted" built-in
try:
    sorted
except NameError:
    def sorted(inlist):
        outlist = list(inlist)
        outlist.sort()
        return outlist

# --------------------------------------------------------------------

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i+n]

# --------------------------------------------------------------------

def rulestringopt(a):
    result = ''
    context = ''
    lastnum = ''
    lastcontext = ''
    for i in a:
        if i in 'BS':
            context = i
            result += i
        elif i in '012345678':
            if (i == lastnum) and (lastcontext == context):
                pass
            else:
                lastcontext = context
                lastnum = i
                result += i
        else:
            result += i
    result = replace(result, '4aceijknqrtwyz', '4')
    result = replace(result, '3aceijknqry', '3')
    result = replace(result, '5aceijknqry', '5')
    result = replace(result, '2aceikn', '2')
    result = replace(result, '6aceikn', '6')
    result = replace(result, '1ce', '1')
    result = replace(result, '7ce', '7')
    return result

clist = []
rule = g.getrule().split(':')[0]

fuzzer = rule + '9'
oldrule = rule
rule = ''
context = ''
deletefrom = []
for i in fuzzer:
    if i == '-':
        deletefrom = [x[1] for x in Hensel[int(context)]]
    elif i in '0123456789/S':
        if deletefrom:
            rule += ''.join(deletefrom)
            deletefrom = []
        context = i
    if len(deletefrom) == 0:
        rule += i
    elif i in deletefrom:
        deletefrom.remove(i)
rule = rule.strip('9')

if not (rule[0] == 'B' and '/S' in rule):
    g.exit('Please set Golly to a two-state isotropic rule.')

if g.empty():
    g.exit('The pattern is empty.')

s = g.getstring('Enter the period:', '', 'Rules calculator')
if not validint(s):
    g.exit('Bad number: %s' % s)

numsteps = int(s)
if numsteps < 1:
    g.exit('Period must be at least 1.')

g.select(g.getrect())
g.copy()
s = int(s)

for i in range(0,s):
    g.run(1)
    clist.append(list(chunks(g.getcells(g.getrect()), 2)))
    mcc = min(clist[i])
    clist[i] = [[x[0] - mcc[0], x[1] - mcc[1]] for x in clist[i]]

g.show('Processing...')

ruleArr = rule.split('/')
ruleArr[0] = ruleArr[0].lstrip('B')
ruleArr[1] = ruleArr[1].lstrip('S')

b_need = []
b_OK = []
s_need = []
s_OK = []

context = ''
fuzzed = ruleArr[0] + '9'
for i in fuzzed:
    if i in '0123456789':
        if len(context) == 1:
            b_need += Hensel[int(context)]
            b_OK += Hensel[int(context)]
        context = i
    elif context != '':
        b_need.append(context[0] + i)
        b_OK.append(context[0] + i)
        context += context[0]
context = ''
fuzzed = ruleArr[1] + '9'
for i in fuzzed:
    if i in '0123456789':
        if len(context) == 1:
            s_need += Hensel[int(context)]
            s_OK += Hensel[int(context)]
        context = i
    elif context != '':
        s_need.append(context[0] + i)
        s_OK.append(context[0] + i)
        context += context[0]

for i in [iter2 for iter1 in Hensel for iter2 in iter1]:
    if not i in b_OK:
        b_OK.append(i)
        execfor = 1
        # B0 and nontotalistic rulestrings are mutually exclusive
        try:
            g.setrule(rulestringopt('B' + ''.join(b_OK) + '/S' + ruleArr[1]))
        except:
            b_OK.remove(i)
            execfor = 0
        for j in range(0, s * execfor):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    b_OK.remove(i)
                    break
            except:
                b_OK.remove(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        b_OK.sort()

    if not i in s_OK:
        s_OK.append(i)
        execfor = 1
        # B0 and nontotalistic rulestrings are mutually exclusive
        try:
            g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_OK)))
        except:
            s_OK.remove(i)
            execfor = 0
        for j in range(0, s * execfor):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    s_OK.remove(i)
                    break
            except:
                s_OK.remove(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        s_OK.sort()

    if i in b_need:
        b_need.remove(i)
        g.setrule(rulestringopt('B' + ''.join(b_need) + '/S' + ruleArr[1]))
        for j in range(0, s):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    b_need.append(i)
                    break
            except:
                b_need.append(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        b_need.sort()

    if i in s_need:
        s_need.remove(i)
        g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_need)))
        for j in range(0, s):
            g.run(1)
            try:
                dlist = list(chunks(g.getcells(g.getrect()), 2))
                mcc = min(dlist)
                dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
                if not(clist[j] == dlist):
                    s_need.append(i)
                    break
            except:
                s_need.append(i)
                break
        g.new('')
        g.paste(0, 0, 'or')
        g.select(g.getrect())
        s_need.sort()

g.setrule(oldrule)
ruleres = 'B' + ''.join(sorted(b_need)) + '/S' + ''.join(sorted(s_need)) + \
    ' - B' + ''.join(sorted(b_OK)) + '/S' + ''.join(sorted(s_OK))
ruleres = rulestringopt(ruleres)
g.show(ruleres)

Re: Script request thread

Posted: July 31st, 2022, 8:13 pm
by atavoidirc
carsoncheng wrote: July 23rd, 2022, 4:36 am
I don't know of any Golly scripts that can convert an apgcode in such rules to an RLE. I am posting the lifelib solution because I thought you might be writing a lifelib script. However, the lifelib script above works for all rules, as far as I know. Therefore, I suggest rewriting your script with lifelib if you would like to.
how do you use lifelib scripts?

Re: Script request thread

Posted: August 1st, 2022, 7:45 am
by carsoncheng
If you want to set up lifelib, run:

Code: Select all

pip install python-lifelib
After that, you can import the module and run the setup script in your lifelib program:

Code: Select all

import lifelib
sess = lifelib.load_rules('b3s23')
lt = sess.lifetree()
If you still have trouble setting up lifelib, please visit this documentation page on the lifelib repository:
https://gitlab.com/apgoucher/lifelib/blob/master/doc/quickstart.md

Re: Script request thread

Posted: August 2nd, 2022, 7:35 pm
by atavoidirc
an inflator script, one that applies inflation to a pattern.

Re: Script request thread

Posted: August 2nd, 2022, 8:16 pm
by Ian07
atavoidirc wrote: August 2nd, 2022, 7:35 pm an inflator script, one that applies inflation to a pattern.
EDIT: Removing my original script since it was vastly inferior in terms of speed, and replacing with a modified version of LaundryPizza03's script. Still has separate scale factors for x and y.

Code: Select all

import golly as g
from glife import *

# inflate.py
# Automatically inflates the current pattern
# LaundryPizza03, 2020
# Added separate factors for x and y (and set default options to 2)
# Ian07, 2022

try:
    scale_x = g.getstring("Scale factor (x)", "2")
    scale_x = int(scale_x)
except:
    g.exit("Bad integer value: {0}".format(scale_x))

try:
    scale_y = g.getstring("Scale factor (y)", "2")
    scale_y = int(scale_y)
except:
    g.exit("Bad integer value: {0}".format(scale_y))

P0 = g.getcells(g.getrect())
g.new('')
for x in range(scale_x):
    for y in range(scale_y):
        g.putcells(P0,x,y,scale_x,0,0,scale_y)

Re: Script request thread

Posted: August 2nd, 2022, 8:28 pm
by confocaloid
There is also this script for inflating.

Re: Script request thread

Posted: August 3rd, 2022, 4:33 pm
by atavoidirc
Multistate version of the Apgcode-to-clipboard-RLE golly script.

Re: Script request thread

Posted: August 7th, 2022, 4:08 am
by atavoidirc
A script based on text.py that pulls up a dialogue box where you input text as well as select a font, than the rle gets pasted to clipboard.

Re: Script request thread

Posted: October 1st, 2022, 9:43 pm
by Cyclotrons
I want a script that creates a .rule file of a rule with StateInvestigator-like states for any given INT rule.

Re: Script request thread

Posted: October 6th, 2022, 9:22 pm
by rattlesnake
I want a script that converts a .mc file to a .rle file.

Re: Script request thread

Posted: October 7th, 2022, 11:24 am
by carsoncheng
rattlesnake wrote: October 6th, 2022, 9:22 pm I want a script that converts a .mc file to a .rle file.
Here it is:

Code: Select all

mc = '''Macrocell file here'''
import lifelib
sess = lifelib.load_rules('b3s23')
lt = sess.lifetree(n_layers=1)
print(lt.pattern(mc).rle_string())
You need to modify the mc variable to read a file to see the pattern in the macrocell format. You also need to install lifelib for the script to run.

But most of the time mc files are used when the patterns grow really colossal (like the caterpillar or the waterbear, which are engineered spaceships). For example, the caterpillar mc file used as the input to the script is 6.7 megabytes, which is already huge, and if you write the RLE to a file, you will have a 30-megabyte file. So most of the time dealing with such enormous patterns actually doesn't require the RLE format. The macrocell format is enough for it to be reconstructed using Golly or lifelib.

Re: Script request thread

Posted: October 10th, 2022, 1:41 am
by rattlesnake
carsoncheng wrote: October 7th, 2022, 11:24 am
rattlesnake wrote: October 6th, 2022, 9:22 pm I want a script that converts a .mc file to a .rle file.
Here it is:

Code: Select all

...
You need to modify the mc variable to read a file to see the pattern in the macrocell format. You also need to install lifelib for the script to run.

But most of the time mc files are used when the patterns grow really colossal (like the caterpillar or the waterbear, which are engineered spaceships). For example, the caterpillar mc file used as the input to the script is 6.7 megabytes, which is already huge, and if you write the RLE to a file, you will have a 30-megabyte file. So most of the time dealing with such enormous patterns actually doesn't require the RLE format. The macrocell format is enough for it to be reconstructed using Golly or lifelib.
When I run this script, I get this error:

Code: Select all

Traceback (most recent call last):
  File "D:/Python/waterbear.py", line 4, in <module>
    lt = sess.lifetree(n_layers=1)
  File "D:\Python\lib\site-packages\lifelib\pythlib\session.py", line 239, in lifetree
    return Lifetree(self, *args, **kwargs)
  File "D:\Python\lib\site-packages\lifelib\pythlib\session.py", line 25, in __init__
    self.ptr = lifelib('CreateLifetree', memory, n_layers)
  File "D:\Python\lib\site-packages\lifelib\pythlib\lowlevel.py", line 206, in __call__
    retval = pickle.load(self.the_library.stdout)
_pickle.UnpicklingError: invalid load key, '/'.

Re: Script request thread

Posted: October 10th, 2022, 10:06 am
by dvgrn
rattlesnake wrote: October 10th, 2022, 1:41 am
carsoncheng wrote: October 7th, 2022, 11:24 am You also need to install lifelib for the script to run.
When I run this script, I get this error:

Code: Select all

{lifelib-related error}
Did you install lifelib? If so, did you run into any problems that might be useful to report?

It's always a good idea to mention your operating system and Golly version when reporting an error.

That said, invoking lifelib for a problem like this does seem like it's dragging in a huge unnecessary dependency. Golly has Lua embedded in it, such that there's no need to install anything else at all. If you open the .mc file in Golly as a starting point, then you can run this to get an RLE file:

Code: Select all

local g = golly()

currentname = g.getname()

if not string.find(currentname, "%.mc") then
  g.note("Current pattern is not named like a macrocell file. Saving an RLE anyway...")
  trialfname = "pattern.rle"
else
  trialfname = string.gsub(currentname,"%.mc",".rle")
end

local fname = g.savedialog("Save RLE file", "RLE files (*.rle)|*.rle", "", trialfname)
if #fname > 0 then
  g.save(fname,"rle")
  g.show("File saved as "..fname..".")
end
If you want it with no manual intervention in Golly, then the following would be generally equivalent to carsoncheng's script, where you'd have to edit the input filename manually:

Code: Select all

local g = golly()

-- edit the following two lines to add valid paths, to get a working sample
inputfname = "your/path/to/Golly/Patterns/HashLife/Eventful/jagged.mc"
outputfname = "your/path/to/where/you/want/jagged.rle"

g.addlayer()
g.open(inputfname)
g.save(outputfname,"rle")
g.dellayer()
g.show("File saved as "..outputfname..".")
-- Of course, if you take one step in the opposite direction, you don't need a script at all -- just open the file in Golly and save it in RLE format.

EDIT by Andrew: fixed some problems in the above scripts.

Re: Script request thread

Posted: October 10th, 2022, 6:24 pm
by rattlesnake
Thanks.

Re: Script request thread

Posted: November 18th, 2022, 4:11 pm
by Book
Is there a script to determine an oscillator's kinetic symmetry?

Re: Script request thread

Posted: November 23rd, 2022, 11:14 am
by IlTifoneHaiyan
Is there a script to generalize LifeOnTheEdge rule?
Thank you.

Re: Script request thread

Posted: December 13th, 2022, 9:17 pm
by pipsqueek
is there a script that can find the smallest phase of an oscillator? (in population)

Re: Script request thread

Posted: December 13th, 2022, 9:59 pm
by dvgrn
pipsqueek wrote: December 13th, 2022, 9:17 pm is there a script that can find the smallest phase of an oscillator? (in population)
There's this code that I used to get minimum population and bounding box for some of the big self-constructing spaceships. Some patience is required for huge patterns, but otherwise it should work fine.

Re: Script request thread

Posted: December 19th, 2022, 5:26 pm
by Anivec
I want a script that converts each step of a catalogue synthesis into a 1G seed composed of spartan splitters, OTTs, etc.

It can also be paired with slmake for multiple purposes.

Re: Script request thread

Posted: February 6th, 2023, 2:28 pm
by HartmutHolzwart
I'd like to have a script that classifies teh evolution of random patterns similar to agpsearch, only on small witdh tubes. I'm only interested in moving patterns, so we'd have spaceships, waves and super strings. And puffer forms thereof.

I would be completely OK with a local python or lua version. This might be too much special interest for catagolue.

Re: Script request thread

Posted: April 15th, 2023, 8:36 pm
by atavoidirc
a script that provides a census of a single pattern