Script request thread

For scripts to aid with computation or simulation in cellular automata.
User avatar
pzq_alex
Posts: 776
Joined: May 1st, 2021, 9:00 pm
Location: tell me if you know

Re: Script request thread

Post by pzq_alex » April 16th, 2023, 10:17 am

atavoidirc wrote:
April 15th, 2023, 8:36 pm
a script that provides a census of a single pattern
Pipe into apgsearch running some stdin symmetry.
\sum_{n=1}^\infty H_n/n^2 = \zeta(3)

How much of current CA technology can I redevelop "on a desert island"?

hkoenig
Posts: 236
Joined: June 20th, 2009, 11:40 am

Re: Script request thread

Post by hkoenig » April 19th, 2023, 9:12 pm

On my list of things to do is a rewrite/replacement of my partition and census functions, if I can find the time. The methods I wrote date back to the last century and could use an update. I'd like to look at how apgsearch (or lifelib) does this and look for ideas to steal. Pointers to the relevant files and functions would be appreciated. Or broad descriptions of what it is doing.

User avatar
pzq_alex
Posts: 776
Joined: May 1st, 2021, 9:00 pm
Location: tell me if you know

Re: Script request thread

Post by pzq_alex » April 24th, 2023, 9:02 am

hkoenig wrote:
April 19th, 2023, 9:12 pm
On my list of things to do is a rewrite/replacement of my partition and census functions, if I can find the time. The methods I wrote date back to the last century and could use an update. I'd like to look at how apgsearch (or lifelib) does this and look for ideas to steal. Pointers to the relevant files and functions would be appreciated. Or broad descriptions of what it is doing.
The bulk of code responsible for separating patterns into objects belongs to https://gitlab.com/apgoucher/lifelib/-/ ... assifier.h . It uses a disjoint-set-union data structure.
\sum_{n=1}^\infty H_n/n^2 = \zeta(3)

How much of current CA technology can I redevelop "on a desert island"?

atavoidirc
Posts: 45
Joined: April 14th, 2022, 3:09 pm

Re: Script request thread

Post by atavoidirc » June 29th, 2023, 2:02 pm

A script that takes a glider synthesis and convert it to Quadlife by coloring the gliders according to direction.

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

Re: Script request thread

Post by dvgrn » June 29th, 2023, 4:09 pm

atavoidirc wrote:
June 29th, 2023, 2:02 pm
A script that takes a glider synthesis and convert it to Quadlife by coloring the gliders according to direction.
That's an easy hack from glider-rewinder.py:

Code: Select all

# glider-colorizer-by-direction-QuadLife.py
# https://conwaylife.com/w/index.php?title=Rule:QuadLife&action=raw
#
# If you have a selection, then only the gliders inside the selection will get updated.
# The others will stay in state 1, which is supposed to be the color for NW-traveling gliders

import golly as g
import os
import itertools
from glife import *

lib=[["NW","bo$2o$obo!"],["NE","2o$b2o$o!"],["SE","obo$b2o$bo!"],["SW","2bo$2o$b2o!"]]

def getenvelope(pat):
  env=[]
  if len(pat)%2:
    g.exit("Must be a 2-state list.")
  for i in range(0,len(pat)-1,2):
    for x in range(-1,2):
      for y in range(-1,2):
        if abs(x)!=0 or abs(y)!=0: # add eight neighbors of each ON cell to the mask
          if [pat[i]+x,pat[i+1]+y] not in env:
            env.append([pat[i]+x,pat[i+1]+y])
  for i in range(0,len(pat),2):
    if [pat[i],pat[i+1]] in env:
      env.remove([pat[i],pat[i+1]]) # take original pattern back out of mask
    # else: # with the reduced envelope, this will now happen, e.g. with *WSS singleton sparks
    #  g.note("Technical error: " + str([pat[i],pat[i+1]])+ " not in envelope:" + str(env) + " \n\n" + str(pat)) 
  return list(itertools.chain.from_iterable(env))

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.")
if len(sel)%2: g.exit("Can't do colorization starting with a multistate rule.  Try Alt+J / Option+J first.")
all = g.getcells(g.getrect())
allcoords=[]
for i in range(0,len(all),2):
  allcoords.append([all[i],all[i+1]])

# g.show("Processing object library...")
odict=dict()
for i in range(len(lib)):
  # g.show("Processing object " + lib[i][0])
  # run and normalize each library object until a duplicate of the original pattern appears
  # The number of ticks to duplication, and the offset, give all the information needed to rewind...
  obj = g.parse(lib[i][1])
  basex, basey,ticks,newobj=obj[0],obj[1],0,[]
  baseobj = g.transform(obj,-basex,-basey)
  basepat = pattern(baseobj) # use glife to avoid having to add a layer in Golly
  
  # TODO: figure out the actual right way to compare in Python 3.x... baseobj>newobj or baseobj<newobj, maybe?
  while str(baseobj) != str(newobj):
    ticks+=1
    newpat=basepat[ticks]
    newlist = list(newpat)
    newobj=g.transform(newpat,-newlist[0],-newlist[1])
    if ticks>999:
      g.exit(obj[0] + " in library has no reasonable repeat time.")
  stridex,stridey=newlist[0],newlist[1]
  
  # odict key is name+phase, and there's an entry for each phase of each object
  # Contains list of repeat, stridex, stridey, dx, dy, clist, envclist.
  # By convention, the first ON cell in phase 0 is at (0,0) and dx and dy are also 0,0.
  # The first ON cell in other phases is also 0,0 but dx and dy will be altered appropriately.
  
  odict[lib[i][0]+"_0"]=[ticks, stridex, stridey, 0, 0, baseobj, getenvelope(baseobj)]
  for t in range(1,ticks):
    newlist=list(basepat[t])
    normalized=g.transform(newlist,-newlist[0],-newlist[1])
    odict[lib[i][0]+"_"+str(t)]=[ticks,stridex,stridey,newlist[0],newlist[1],normalized,getenvelope(normalized)]
g.show("")

# make a list of coordinate pairs that might be Objects of Interest (gliders or LWSSes)
coords=[]
for i in range(0,len(sel),2):
  coords.append([sel[i],sel[i+1]])

rewindable=[]
# now go through the selection and find all the recognizable patterns
i=0
while i<len(coords):
  x0,y0=coords[i][0], coords[i][1]
  for k, v in list(odict.items()):
    clist = v[5] # object cell list
    match=1
    for j in range(0,len(clist),2):
      if [x0+clist[j],y0+clist[j+1]] not in coords:
        match=0
        break # a cell in this object is not in the selected pattern
    if match:
      envclist=v[6] # object envelope cell list
      for j in range(0,len(envclist),2):
        if [x0+envclist[j],y0+envclist[j+1]] in allcoords: # could use coords instead, but selection should be increased 2 cells all around
          match=0
          break # a cell in the surrounding must-be-OFF area is ON
    if match:
      # remove all recognized cells from coords
      for j in range(0,len(clist),2):
        crd=[x0+clist[j],y0+clist[j+1]]
        if crd in coords:
          coords.remove(crd)
        else:
          g.exit("A coordinate that should have been there wasn't: " + str(crd) + "\n\n" + str(coords))
      rewindable.append([k,x0-v[3],y0-v[4]])
      break # no need to go through rest of items in dictionary
  if not match:
    i+=1 # only increment index if current coord has not been removed due to a match

g.setrule("QuadLife")
# color all gliders
for item in rewindable:
  lookup=odict[item[0]]
  # odict[name+phase]=[ticks, stridex, stridey, dx, dy, clist, getenvelope(clist)]
  clist = lookup[5]
  
  # lookup[1] and lookup[2] will contain each glider's x and y offsets every four ticks --
  #   convert those numbers into a value from 1 to 4
  color = (lookup[1]*4+lookup[2]*2 + 10) // 4
  
  for i in range(0,len(clist),2):
    g.setcell(clist[i]+item[1]+lookup[3],clist[i+1]+item[2]+lookup[4],color)

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

Re: Script request thread

Post by erictom333 » August 17th, 2023, 6:30 am

A script to determine critical mass of a rule. Something along the lines of:

Code: Select all

Set n to some preset number (16?)
While necessary {
	Repeat 1000 times {
		Run a random n*n soup
		Check if it stabilises
	}
	If a majority of soups do not stabilise {
		Choose larger n
	} Else {
		Choose smaller n
	}
}
Return smallest n such that a majority of n*n soups do not stabilise

User avatar
b3s23love
Posts: 79
Joined: May 24th, 2023, 6:30 am
Location: The (Life?) Universe

Re: Script request thread

Post by b3s23love » September 13th, 2023, 4:47 pm

(moved from script-related questions because this is a better thread for this)
Would someone like to provide a stdin script for apgsearch that provides multistate random soups?

User avatar
confocaloid
Posts: 1169
Joined: February 8th, 2022, 3:15 pm

Re: Script request thread

Post by confocaloid » September 13th, 2023, 9:23 pm

Barring bugs, this Python 3 script should print a given number of multistate soups. Change the constants at the beginning as needed. No express or implied warranty.

Code: Select all

import random

################################################################################
# The number of cellstates:
N_STATES    = 16
# The rulestring to be used:
RULESTRING  = "QuadB3S23"
# The number of columns:
RLE_WIDTH   = 16
# The number of rows:
RLE_HEIGHT  = 16
# The number of RLEs to generate (set to 0 to run 'forever'; set to 10 to generate 10 RLEs, etc.)
N_RLES      = 0
################################################################################

def random_cellstate():
  return random.randrange(0, N_STATES)

S1 = ["", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y"]
S2 = "ABCDEFGHIJKLMNOPQRSTUVWX"

def cellstate_to_rle(c):
  if c == 0:
    return "."
  return S1[(c - 1) // 24] + S2[(c - 1) % 24]

def random_rle():
  rle = ""
  for y in range(RLE_HEIGHT):
    rle = rle + "".join(cellstate_to_rle(random_cellstate()) for x in range(RLE_WIDTH))
    rle = rle + "{}\n".format("$" if y < RLE_HEIGHT - 1 else "!")
  return "x = {}, y = {}, rule = {}\n{}".format(RLE_WIDTH, RLE_HEIGHT, RULESTRING, rle)

def main():
  print(random_rle())
  i = 1
  while i != N_RLES:
    print(random_rle())
    i += 1

main()
127:1 B3/S234c User:Confocal/R (incomplete table of INT rules)
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.

Post Reply