This WIP script so far calculates the subperiods for each cell and outputs them to a txt file. g.show if trivial or non-trivial.
The main idea for the next step is to separate xp4 and xp2, for example, that are "on" a still life yet don't interact, something that Oscillizer cannot do (I mean, you can obviously see it by looking at it, but that's not what I mean).
How?
After looking at a few examples, I've noticed that for any subperiod=S cell in a fully non-trivial oscillator, there always is a polyplet that connects that cell to a full period cell so that every cell in that polyplet has a period > 1.
It sounds like a bit of a mouthful but if you look at it with an example you'll quickly see what I mean.
That's the tricky bit of the script, but it would end up being the more useful part.
Anyway, here's what I have so far and the comments at the bottom explain what I need help with.
Code: Select all
# trivialhunter.py
# Author: Rhombic
# For a given oscillator, returns "cell_periods.txt" with the subperiod for each individual cell.
# Shows in Golly whether the oscillator is trivial and, if so, what the maximum period is.
# For future development see the comments at the bottom.
import golly as g
def periodic(M):
incase = 0
for checkeach in xrange(len(M)-1):
if M[checkeach+1]!=M[checkeach]:
return 0
return 1
p = int(g.getstring("Period: ","1"))
rect = g.getrect()
for gen in xrange(p):
g.run(1)
if g.getrect()[2]>rect[2]:
rect[0]=g.getrect()[0]
rect[2]=g.getrect()[2]
if g.getrect()[3]>rect[3]:
rect[1]=g.getrect()[1]
rect[3]=g.getrect()[3]
factors = []
File = open("cell_periods.txt","w+")
File.write("x\ty\tperiod\n")
triviality=1
maxp=1
for i in xrange(p):
if p%(i+1)==0: factors.append(i+1)
for x in xrange(rect[2]):
for y in xrange(rect[3]):
done = 0
statelist=[]
statelist.append(g.getcell(rect[0]+x,rect[1]+y))
for j in xrange(p):
g.run(1)
statelist.append(g.getcell(rect[0]+x,rect[1]+y))
for frac in xrange(len(factors)):
psub = 1
subperiod=statelist[:factors[frac]]
for repetition in xrange(p/factors[frac]):
if statelist[repetition*factors[frac]:(repetition+1)*factors[frac]]!=subperiod: psub = 0
if psub == 1 and done == 0:
File.write(str(rect[0]+x)+"\t"+str(rect[1]+y)+"\t"+str(factors[frac])+"\n")
done = 1
if factors[frac]==p: triviality=0
else: maxp=max(maxp,factors[frac])
if triviality==1: g.show("Trivial oscillator, with a maximum cell period of "+str(maxp)+".")
else: g.show("Non-trivial oscillator.")
File.close()
# OK, next step is the following:
# For a non-trivial oscillator:
# For each cell that does NOT oscillate full period:
# Try to find a polyplet path from that cell to any full-period cell
# EXCLUSIVELY through period>1 cells (that is, a polyplet through state 0 is useless)
# Why, Ed, isn't that just a waste of time?
# No, because that way you can separate trivial xp(a*b)--xp(a) interactions,
# which the current script is unable to do. e.g. blocker on beacon