Script request thread

For scripts to aid with computation or simulation in cellular automata.
User avatar
confocaloid
Posts: 6697
Joined: February 8th, 2022, 3:15 pm
Location: learn to protect yourself against stray gliders and sparks and self-destruct mechanisms

Re: Script request thread

Post by confocaloid » May 6th, 2025, 6:52 am

Citation needed wrote:
May 6th, 2025, 6:29 am
Are there Python functions for Golly that can simulate these commands without putting a size limit (the grammar can be different but it should be easy to learn)? "showinviewer.lua" is in Lua, but it unfortunately also had the size limit from LifeViewer, and ColorfulGalaxy knows nothing about Lua. [...]
That "ColorfulGalaxy knows nothing about Lua" doesn't sound like a very good reason why you shouldn't know anything about Lua.
there is Golly's documentation: https://golly.sourceforge.io/Help/lua.html
there are some example scripts: viewtopic.php?f=9&t=6913 and those provided with Golly
and then of course there are various online resources on programming in Lua.

As a side note, rather than trying to simulate LifeViewer's "PASTE" tricks and other non-CA scripting commands directly, I would be more interested in finding a way to convert such "imaginary evolutionary sequences" into actual evolutionary sequences in multistate cellular automata supported by the RuleLoader algo. Preferably arbitrary finite sequences of frames, and preferably isotropic cellular automata, but there could be impossibilities preventing that. viewtopic.php?p=209757#p209757
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
pifricted
Posts: 968
Joined: May 25th, 2024, 10:26 am
Location: Behind The Great Internet Wall

Re: Script request thread

Post by pifricted » August 14th, 2025, 10:10 am

Is there a RegExp for RLE?
pifricted's rules & pifricted's Sandbox User:Pifricted
Ehhh…
I’m not a guy good at rule exploration, right?

User avatar
qqd
Posts: 605
Joined: September 10th, 2022, 4:24 pm
Location: In a superposition of multiple different locations.

Re: Script request thread

Post by qqd » August 24th, 2025, 8:32 am

Is there a script in Lua (Lua specifically!) where I can input an output Herschel's position, rotation, and chirality with respect to an input Herschel, and get a composite or elementary conduit which can transport a Herschel to that location with the least ticks possible? (And without using spaceship-to-X's ?)

Such a script should be possible, considering the original universal set of 16 Herschel conduits + hundreds more that have been found to transport Herschels and other objects.
Currently writing a utility in Lua that may be helpful for faster manual pattern manipulation.

User avatar
dvgrn
Moderator
Posts: 11980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Script request thread

Post by dvgrn » August 24th, 2025, 3:02 pm

qqd wrote:
August 24th, 2025, 8:32 am
Is there a script in Lua (Lua specifically!) where I can input an output Herschel's position, rotation, and chirality with respect to an input Herschel, and get a composite or elementary conduit which can transport a Herschel to that location with the least ticks possible? (And without using spaceship-to-X's ?)
Definitely that doesn't exist in Lua yet. We used to have something called Hersrch, written by Karel Suhajda in C++, which worked on Herschel conduits only. There's a Hersrch input mode that lets you do exactly what you're describing. It would give you as many options as you wanted to look at (limiting to the first 20 most compact, or whatever).

These days, for a fairly good percentage of spacetime output locations, the "least ticks possible" actually would use a Herschel-to-MWSS in it somewhere, followed by an MWSS-to-Herschel. And/or it would use elementary conduits like BRx46B, not just the Herschel conduits that Hersrch knew about.

The thing that might make the most sense would be to pre-compute tested good options for every possible offset and orientation, and put them in a big database -- no point in re-computing them on demand if we can just figure them all out once and then look them up. That would reduce the Lua script to a very simple lookup operation.

User avatar
Sylvani
Posts: 146
Joined: September 26th, 2024, 3:23 am

Re: Script request thread

Post by Sylvani » August 28th, 2025, 12:13 am

Can someone make a modification to qfind that outputs each best partial from each depth it reaches instead of just at the end?

Sokwe
Moderator
Posts: 3368
Joined: July 9th, 2009, 2:44 pm

Re: Script request thread

Post by Sokwe » August 28th, 2025, 2:28 am

Sylvani wrote:
August 28th, 2025, 12:13 am
Can someone make a modification to qfind that outputs each best partial from each depth it reaches instead of just at the end?
I'm not sure what you mean by "best partial". The state is only dumped after a queue compaction, and at that time all partials are equally long, with partials that were too short having been eliminated. The partials for a particular dump file can be listed by running

Code: Select all

./qfind -l <dump-file> -p
If you want the queue compaction to be performed at each new depth, you can use the --fixed-depth option which gives a more traditional breadth-first search with a limited level of deepening. You can then use "-a 0" to dump the state after each compaction (well, it would if I had implemented it correctly, but it currently has a minimum interval of 1 second between dumps) and use "--dump-mode sequential" to label the dump files with numbers instead of blue/gold. For example, you could run

Code: Select all

./qfind -r B3/S23 -v c/5 -w 9 -s even -t 4 -a 0 --dump-mode sequential --fixed-depth 30
which will dump the state at nearly every new depth after running depth-first lookahead to level 30 on each new queue node. You can then preview the partial results at each depth with "./qfind -l <dump-file> -p" as noted above.

If you want to fix the code so that you can truly set the dump interval (-a option) to 0, simply edit the line in common.h that reads

Code: Select all

   if (params[P_DUMPMODE] != D_DISABLED && time(NULL) - lastDumpTime > params[P_DUMPINTERVAL]){
to instead read

Code: Select all

   if (params[P_DUMPMODE] != D_DISABLED && time(NULL) - lastDumpTime >= params[P_DUMPINTERVAL]){
-Matthias Merzenich

User avatar
PK22
Posts: 564
Joined: January 25th, 2025, 11:38 am
Location: United Kingdom

Re: Script request thread

Post by PK22 » August 28th, 2025, 5:07 pm

Can someone rewrite one of the scripts in the post below so that it generates random 10G collisions with D2_x symmetry?
goldenratio wrote:
December 27th, 2020, 8:21 pm
C++ port to the D2 collision enumerator posted earlier (with some code cleanups)

D2_+1:

Code: Select all

code
D2_+2:

Code: Select all

code
EDIT: This can on occasion produce invalid syntheses, but occurrences are much less frequent than the asymmetric generator.
Also this obviously won't find syntheses for non-gutter-symmetric patterns.
EDIT 2 (1-18-2021): I think I fixed the glider positioning bug. The scripts should now be fully functional.
User:PK22
Currently taking exams; unlikely to be active until mid June.
15/25 exams completed.

Citation needed
Posts: 682
Joined: April 1st, 2021, 1:03 am

Re: Script request thread

Post by Citation needed » September 20th, 2025, 8:44 am

Is there a Python script that converts an RLE to an XPM image (workaround for a "visual rule-icon editor")?

Scripts that work on "Try it online" are preferred.

User avatar
dvgrn
Moderator
Posts: 11980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Script request thread

Post by dvgrn » September 20th, 2025, 9:55 pm

Citation needed wrote:
September 20th, 2025, 8:44 am
Is there a Python script that converts an RLE to an XPM image (workaround for a "visual rule-icon editor")?

Scripts that work on "Try it online" are preferred.
What we currently have is Python scripts that are meant to work in Golly -- a matched pair, icon-exporter.py and icon-importer.py. Golly plus these two included scripts really does amount to a "visual rule-icon editor".

icon-exporter.py uses a Golly layer rather than an RLE file as the source of icon information, but it would be a fairly straightforward job of re-coding to start from an RLE file instead.

User avatar
LuveelVoom
Posts: 463
Joined: April 27th, 2022, 7:59 pm

Re: Script request thread

Post by LuveelVoom » September 24th, 2025, 8:50 pm

A non-python program (I can't run python within my Golly instance) that does the following for any INT rule:
1. Takes in an active region and a set of target objects
2. Positions the target objects around the active region in all places where they could interact with the active region and in all phases and orientations of the target objects
3. Outputs any interaction where the target object is still in the original position after a specified amount of time (e.g. a catalysis)
OCA primer (WIP): User:LuveelVoom/A_Primer_On_OCA
My rules: viewtopic.php?f=11&t=6843
YBOCAD: viewtopic.php?f=11&t=7036
Discord user: LuveelVoom

User avatar
ThePlayzr
Posts: 698
Joined: April 19th, 2025, 1:33 am
Location: Australia
Contact:

Re: Script request thread

Post by ThePlayzr » September 26th, 2025, 8:42 pm

LuveelVoom wrote:
September 24th, 2025, 8:50 pm
A non-python program (I can't run python within my Golly instance) that does the following for any INT rule:
1. Takes in an active region and a set of target objects
2. Positions the target objects around the active region in all places where they could interact with the active region and in all phases and orientations of the target objects
3. Outputs any interaction where the target object is still in the original position after a specified amount of time (e.g. a catalysis)
I disagree with 'could interreact with the active region and in all phases and orientations of the target objects', because what about a loaf on the very edge? If we reorientated it, it would not interreact, but in its current orientation, it does interreact. So, I think it should be 'and in the phases and the orientation of the target object'.
Edit: I request a script that lists out all still lives with a specified population in any INT rule.
Edit 2: is progress being made to making our scripts?
Please help me prove b3s23-a5 omniperiodic!
Please visit my ruleset and contribute!
User:ThePlayzr
Finally got LLS! Time to do way too much searching!

EDen68
Posts: 5
Joined: September 27th, 2025, 1:37 pm

Re: Script request thread

Post by EDen68 » October 4th, 2025, 1:38 pm

Can I please have an isotropic 0e0p metafier for golly?

User avatar
dvgrn
Moderator
Posts: 11980
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Script request thread

Post by dvgrn » October 5th, 2025, 12:58 am

EDen68 wrote:
October 4th, 2025, 1:38 pm
Can I please have an isotropic 0e0p metafier for golly?
This wouldn't be entirely impossible to do in a plain-vanilla Python script running inside Golly. But writing it would require rewriting a lot of useful lifelib functionality to work rather inefficiently in Python. This is why the existing isotropic 0e0p metafier relies on lifelib.

102564
Posts: 29
Joined: October 27th, 2025, 6:32 pm

Re: Script request thread

Post by 102564 » November 9th, 2025, 9:21 pm

Some explosive rules are searchable via stdin symmetries, but they search very slowly and can get stuck. I've been trying to apgsearch B3ai4cet5c6c7cS2a3-kqr4eqt5i6cei78 using a stdin symmetry, but it is very slow (~1 soup per second, also using a stdin symmetry disallows parallelization) and tends to get stuck after a few hundred soups. This makes it infeasible to do one haul with a large number of soups (maybe 10000). It is still possible to do many small hauls instead, but that gives unnecessary work to Catagolue. So the idea is then to do many small hauls and combine their results to upload as a large haul.

I request a Python script that does the following:
1. Get all the apgsearch log files of a given rule and symmetry from the current directory
2. Get the apgcodes, number of occurrences, and example soups from each log file
3. Combine the results from step 2 and upload to Catagolue
Thanks!

User avatar
dl-rs
Posts: 247
Joined: April 11th, 2022, 12:14 am
Location: I was just a block until a glider crashes with me and I tumbled onto Earth surface in LWSS form.
Contact:

Re: Script request thread

Post by dl-rs » November 16th, 2025, 5:58 am

102564 wrote:
November 9th, 2025, 9:21 pm
Some explosive rules are searchable via stdin symmetries, but they search very slowly and can get stuck. I've been trying to apgsearch B3ai4cet5c6c7cS2a3-kqr4eqt5i6cei78 using a stdin symmetry, but it is very slow (~1 soup per second, also using a stdin symmetry disallows parallelization) and tends to get stuck after a few hundred soups. This makes it infeasible to do one haul with a large number of soups (maybe 10000). It is still possible to do many small hauls instead, but that gives unnecessary work to Catagolue. So the idea is then to do many small hauls and combine their results to upload as a large haul.

I request a Python script that does the following:
1. Get all the apgsearch log files of a given rule and symmetry from the current directory
2. Get the apgcodes, number of occurrences, and example soups from each log file
3. Combine the results from step 2 and upload to Catagolue
Thanks!
I've been experiencing similar problems. The search is unbelievably slow.

C1_stdin.cpp:

Code: Select all

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

void parse(int r, int d)
{
    for(int i = 0; i < d; i++)
    if(r & (1 << i))
        cout << 'o';
    else
        cout << 'b';
}

int main()
{
    srand(time(0));
    ios::sync_with_stdio(false);
    while(1)
    {
        cout << "x = 128, y = 128, rule = B3ai4cet5c6c7c/S2a3-kqr4eqt5i6cei78" << endl;
        for(int i = 1; i <= 2; i++)
        {
            for(int j = 1; j <= 128; j++)
            {
                if(j % 3)
                    cout << 'o';
                else
                    cout << 'b';
            }
            cout << '$';
        }
        cout << '$';
        for(int i = 1; i <= 122; i++)
        {
            if(i % 3)
                cout << "oo";
            else
                cout << "bb";
            cout << 'b';
            for(int k = 0; k < 7; k++)
                parse(rand() % 65536, 16);
            parse(rand() % 1024, 10);
            cout << 'b';
            if(i % 3)
                cout << "oo";
            else
                cout << "bb";
            cout << '$';
        }
        cout << '$';
        for(int i = 1; i <= 2; i++)
        {
            for(int j = 1; j <= 128; j++)
            {
                if(j % 3)
                    cout << 'o';
                else
                    cout << 'b';
            }
            if(i == 1)
                cout << '$';
        }
        cout << '!' << endl;
    }
    return 0;
}
Roaming OCA randomly.

Code: Select all

x = 23, y = 11, rule = B2n3-jknr4ky5-eqry6ik7c8/S234cktwz5ai6-ci7c
2bo2b3o2bo7bo2bo$b2ob5ob2o6b2ob2o$2bo2b3o2bo7bo2bo4$10b2o$b3o5bobo$2o
b2o4b3o$b3o5bobo$10b2o!

102564
Posts: 29
Joined: October 27th, 2025, 6:32 pm

Re: Script request thread

Post by 102564 » November 16th, 2025, 11:13 am

Warning: any large haul in B3ai4cet5c6c7c/S2a3-kqr4eqt5i6cei78 is likely to flood the xp section of the Catagolue census.

Here is a Python function that does the first step of combined haul uploading:

Code: Select all

import os
from pathlib import Path
from re import fullmatch
from typing import Generator

FOLDER = Path(__file__).parent

def get_log_files(rule: str | None = None, symmetry: str | None = None) -> Generator[str, None, None]:
    filenames = [f for f in os.listdir(FOLDER) if os.path.isfile(FOLDER / f)]
    for filename in filenames:
        if not fullmatch("log\\.\\d+\\.k_[A-Za-z0-9]+\\.txt", filename):
            continue
        correct_rule = True
        correct_symmetry = True
        with open(FOLDER/ filename, encoding="utf-8") as file:
            for line in file.readlines():
                if line[:5] == "@RULE":
                    log_rule = line[6:-1]
                    correct_rule = log_rule == rule
                elif line[:9] == "@SYMMETRY":
                    log_symmetry = line[10:-1]
                    correct_symmetry = log_symmetry == symmetry
        if not correct_rule and rule is not None:
            continue
        if not correct_symmetry and symmetry is not None:
            continue
        yield filename
For a script that can merge and upload hauls, any programming language will work for me, but if someone did make such a script, I'd prefer Python. Thanks!

Also, here is the stdin script I was using:

Code: Select all

import itertools, os, random

RULE = "b3ai4cet5c6c7cs2a3-kqr4eqt5i6cei78"
NUM_SOUPS = 1000
STDIN_SYMMETRY_NAME = "block_corral_16x16_50x50_C1_stdin"
PAYOSHA256_KEY = "#anon"
RECOMPILE_APGSEARCH = False

def block_corral_soup(rule: str) -> str:
    header = f"x = 50, y = 50, rule = {rule}"

    alive_cells = [(0, 0), (0, 1), (1, 0), (1, 1), (0, 48), (0, 49), (1, 48), (1, 49), (6, 0), (6, 1), (7, 0), (7, 1), (6, 48), (6, 49), (7, 48), (7, 49), (12, 0), (12, 1), (13, 0), (13, 1), (12, 48), (12, 49), (13, 48), (13, 49), (18, 0), (18, 1), (19, 0), (19, 1), (18, 48), (18, 49), (19, 48), (19, 49), (24, 0), (24, 1), (25, 0), (25, 1), (24, 48), (24, 49), (25, 48), (25, 49), (30, 0), (30, 1), (31, 0), (31, 1), (30, 48), (30, 49), (31, 48), (31, 49), (36, 0), (36, 1), (37, 0), (37, 1), (36, 48), (36, 49), (37, 48), (37, 49), (42, 0), (42, 1), (43, 0), (43, 1), (42, 48), (42, 49), (43, 48), (43, 49), (48, 0), (48, 1), (49, 0), (49, 1), (48, 48), (48, 49), (49, 48), (49, 49), (0, 6), (1, 6), (0, 7), (1, 7), (48, 6), (49, 6), (48, 7), (49, 7), (0, 12), (1, 12), (0, 13), (1, 13), (48, 12), (49, 12), (48, 13), (49, 13), (0, 18), (1, 18), (0, 19), (1, 19), (48, 18), (49, 18), (48, 19), (49, 19), (0, 24), (1, 24), (0, 25), (1, 25), (48, 24), (49, 24), (48, 25), (49, 25), (0, 30), (1, 30), (0, 31), (1, 31), (48, 30), (49, 30), (48, 31), (49, 31), (0, 36), (1, 36), (0, 37), (1, 37), (48, 36), (49, 36), (48, 37), (49, 37), (0, 42), (1, 42), (0, 43), (1, 43), (48, 42), (49, 42), (48, 43), (49, 43)]
    for x, y in itertools.product(range(17, 33), range(17, 33)):
        if random.random() < 0.5:
            alive_cells.append((x, y))

    encoding_string = ["b" * 50 + "$"] * 50
    for cell in alive_cells:
        unedited_row = encoding_string[cell[1]]
        encoding_string[cell[1]] = unedited_row[:cell[0]] + "o" + unedited_row[cell[0] + 1:]
    encoding_string = "".join(encoding_string)

    while "b$" in encoding_string:
        encoding_string = encoding_string.replace("b$", "$")

    run_length_encoding = ""
    current_character = encoding_string[:1]
    run_length = 0
    for character in encoding_string:
        if character != current_character:
            run_length_encoding += (str(run_length) if run_length > 1 else "") + current_character
            current_character = character
            run_length = 0
        run_length += 1
    run_length_encoding += "!"

    return header + "\n" + run_length_encoding

print("Generating soups...")
SOUPS = [block_corral_soup(RULE) for i in range(NUM_SOUPS)]
SOUP_FILENAME = f"block_corral{random.randint(1, 2**20)}.txt"
with open(SOUP_FILENAME, mode="w", encoding="utf-8") as file:
    file.write("\n".join(SOUPS))
print(f"Successfully generated {NUM_SOUPS} soups")

if RECOMPILE_APGSEARCH:
    os.system(f"arch -x86_64 ./recompile.sh --rule {RULE} --symmetry {STDIN_SYMMETRY_NAME}")
os.system(f"./apgluxe -n {NUM_SOUPS} --rule {RULE} --symmetry {STDIN_SYMMETRY_NAME} -k {PAYOSHA256_KEY} -i 1 < {SOUP_FILENAME}")
os.remove(SOUP_FILENAME)
The stdin script generates soups that are a 16x16 soup and blocks that block the soup from exploding, with a total bounding box of 50x50. The blocks are spaced 4 cells apart, though blocks spaced 3 cells apart may result in more oscillators. (Blocks spaced 1 cell apart are likely going to cause slowdowns with object separation.)

User avatar
R2INT
Posts: 775
Joined: July 2nd, 2024, 7:42 pm

Re: Script request thread

Post by R2INT » January 29th, 2026, 6:34 pm

I'm curious if a script could be made that takes a given catalysis and outputs the resulting filers/masks that are compatible with CatForce input files (this should also work for isotropic rules). Then, you could pipe the results from a catalyst search program into this script and generate catalyst inputs for CatForce faster than you could do by hand, making CatForce searches easier to do.

(This is most likely to be useful for OCA rules, so it would also be convenient if a catalyst search program exists for INT rules.)
Range-2 INT
R2INT's Rule Collection

Currently missing OCA catalyst search software and OCA conduit search software (the one I have is hardcoded to B3/S23-a5)

erictom333
Posts: 193
Joined: January 9th, 2019, 2:44 am

Re: Script request thread

Post by erictom333 » March 8th, 2026, 6:09 am

I would like a script to analyse infinite growth patterns (specifically guns, puffers, and rakes) similarly to how it is possible to analyse oscillators and spaceships. I would like to extract the following information:
  • Period, displacement, and velocity
    Minimum and maximum population ignoring ash*, and phase of minimum population
    Minimum bounding box ignoring ash*
    Census of the ash* produced every period (for example, 8 blocks for BPSE)
    Minimum, maximum, and average population of the ash* produced every period (for example, 32 for BPSE)
*Cells are classified as ash if they can be removed from the infinite growth without affecting it

User avatar
I6_I6
Posts: 730
Joined: July 26th, 2025, 8:44 pm
Location: Here, there, somewhere, anywhere, everywhere.
Contact:

Re: Script request thread

Post by I6_I6 » April 29th, 2026, 2:45 pm

erictom333 wrote:
March 8th, 2026, 6:09 am
I would like a script to analyse infinite growth patterns (specifically guns, puffers, and rakes) similarly to how it is possible to analyse oscillators and spaceships. I would like to extract the following information:
  • Period, displacement, and velocity
    Minimum and maximum population ignoring ash*, and phase of minimum population
    Minimum bounding box ignoring ash*
    Census of the ash* produced every period (for example, 8 blocks for BPSE)
    Minimum, maximum, and average population of the ash* produced every period (for example, 32 for BPSE)
*Cells are classified as ash if they can be removed from the infinite growth without affecting it
I believe there's a reason a script like this doesn't exist yet, but I'm not entirely sure what that reason is. Growth patterns are kinda hard to classify anyway.

Code: Select all

#C [[ THEME Golly ]]
x = 27, y = 15, rule = LifeHistory
8.A$A6.A.A$3A4.BA2B.B2D$3.A4.2B.2B2DB$2.2A2.3B.6B2.3B$2.20B$4.19B$4.2B
C10BD4B$4.2B2C10BD4B$4.B2C11B2D3B$4.13B2D4B$5.12BD3B.B2A$6.13B3.BA.A$
6.3B.B3.B10.A$25.2A!
User:I6 I6/Elementary Emulators

Post Reply