## Gustavo Ramos Rehermann's patterns

A forum where anything goes. Introduce yourselves to other members of the forums, discuss how your name evolves when written out in the Game of Life, or just tell us how you found it. This is the forum for "non-academic" content.
A for awesome
Posts: 2294
Joined: September 13th, 2014, 5:36 pm
Location: Pembina University, Home of the Gliders
Contact:

### Re: Gustavo Ramos Rehermann's patterns

dvgrn wrote:Other workable workarounds include creating a new layer, pasting in the pattern, and then

1) selecting and copying the pattern out to the clipboard and using g.getclipstr(). But it's not really a good idea to use the clipboard for a low-level task like this, at least without giving users clear warning. People might like what they have in their clipboard, and not want it to be suddenly clobbered by random junk.
There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
praosylen#5847 (Discord)

x₁=ηx
V*_η=c²√(Λη)
K=(Λu²)/2
Pₐ=1−1/(∫^∞_t₀(p(t)ˡ⁽ᵗ⁾)dt)

$$x_1=\eta x$$
$$V^*_\eta=c^2\sqrt{\Lambda\eta}$$
$$K=\frac{\Lambda u^2}2$$
$$P_a=1-\frac1{\int^\infty_{t_0}p(t)^{l(t)}dt}$$

dvgrn
Moderator
Posts: 7585
Joined: May 17th, 2009, 11:00 pm
Contact:

### Re: Gustavo Ramos Rehermann's patterns

A for awesome wrote:There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
Another odd case is when something has been copied that isn't a string. Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.

The clipboard is a strange and uncanny thing, a miracle of rare device. I guess that's why I try to leave it alone, except when I would just be copying something out of some text file as the result of a script anyway.

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

dvgrn wrote:
A for awesome wrote:There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
Another odd case is when something has been copied that isn't a string. Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.

The clipboard is a strange and uncanny thing, a miracle of rare device. I guess that's why I try to leave it alone, except when I would just be copying something out of some text file as the result of a script anyway.

Anyway the script I done is behaving too weird and unfunctionally in a way that can't be described. (plz-hlp)
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

Scorbie
Posts: 1538
Joined: December 7th, 2013, 1:05 am

### Re: Gustavo Ramos Rehermann's patterns

Just to clarify, that was not his point.
dvgrn wrote:Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.
Copying text from WordPad and pasting it directly again doesn't damage anything, but manipulating and restoring the same string damages the format?! Hmm, that's a pretty strange aspect of the clipboard.
Gustavo6046 wrote:Anyway the script I done is behaving too weird and unfunctionally in a way that can't be described. (plz-hlp)
I'm not sure if anyone would willingly spend their time to do your work, especially debugging. For a feeble script-writer like me, that is the most annoying step through writing programs.
Best wishes to you! - Scorbie

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

Can there be a console output as well? I didn't tested print but since there is no console I don't think it would work either.

g.show() don't let you scroll, which is a pity.
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

Scorbie
Posts: 1538
Joined: December 7th, 2013, 1:05 am

### Re: Gustavo Ramos Rehermann's patterns

I pointed out a similar thing recently: viewtopic.php?f=9&t=1965#p25957
Summary: launch Golly from the terminal and you'll see the print statements.
(e.g. by launching /your/path/to/Golly/golly in the terminal)
Best wishes to you! - Scorbie

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

Scorbie wrote:I pointed out a similar thing recently: viewtopic.php?f=9&t=1965#p25957
Summary: launch Golly from the terminal and you'll see the print statements.
(e.g. by launching /your/path/to/Golly/golly in the terminal)
Golly should have a bShowConsole option... I wonder if they are still working in it.
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

This is the VERY FIRST edgy long-boat reaction I've ever found:

Code: Select all

x = 9, y = 13, rule = LifeHistory
6.E$5.E$5.3E7$6.E$5.E.E$2E3.E2.E$2E4.2E!

Unfortunately no use... to a extent...
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

How do I automatically archive the piles of crumbs resultable from that Toaster I? (number of conduits + lots o Snarks) The one I posted earlier, where the snarks are adjustable.
Edit: --
gmc_nxtman wrote:Incremental synthesis (haven't made one with kickbacks yet):

Code: Select all

<rle>

What is a kickback?
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

mniemiec
Posts: 1224
Joined: June 1st, 2013, 12:00 am

### Re: Gustavo Ramos Rehermann's patterns

Gustavo6046 wrote:What is a kickback?
Before asking simple questions like this, you should first try looking on the LifeWiki. You would get your answer in only 3 mouse clicks.

dvgrn
Moderator
Posts: 7585
Joined: May 17th, 2009, 11:00 pm
Contact:

### Re: Gustavo Ramos Rehermann's patterns

Gustavo6046 wrote:How do I automatically archive the piles of crumbs resultable from that Toaster I? (number of conduits + lots o Snarks) The one I posted earlier, where the snarks are adjustable.
Rather than just a vague reference to things like "the one I posted earlier", it would be nice if you'd get in the habit of including a link. I'm a lot more likely to click on a link than to go paging back through this thread to find what you're talking about.

I can't help remembering Toaster I, though! Please consider simplifying your toaster to make a Toaster II before you start collecting crumbs. Whatever crumbs might spew out of Toaster I won't likely be useful for anything, because of the surplus of Snarks surrounding the output location... as mniemiec has explained.

To make an automatic archive: write a script to run through all possible combinations of reflector adjustments -- nested for loops, let's say. For each combination, the script should
• place Snarks at the correct offsets,
• run the pattern,
• check that the Snarks and other catalysts all survive
• remove the Snarks and other catalysts from the pattern
• dump the remaining crumbs to a text file.
One line of text per constellation of crumbs would be good -- maybe use ptbsearch format, or plain headerless RLE.
Gustavo6046 wrote:What is a kickback?
The Life Lexicon (Golly > Help > Life Lexicon) would also be happy to answer this kind of question for you. Kickback reaction. These are used to tighten up continuous syntheses sometimes, at the cost of one more glider per kickback, or to sneak a glider in to a tight recipe where it would otherwise conflict with other incoming gliders.

Kickbacks don't really seem to be necessary in this case. It's a perfectly nice continuous synthesis already, though it's labeled as "incremental".

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

Oh thanks I forgot about LifeWiki & the Lexicon.

I am fixing HRF and making a Cell list to RLE function:

Code: Select all

import golly as g
import time as t

def cell_list_to_rle(debug = False, *cells):

if debug == True:
g.show(str(cells))
t.sleep(1)

top = None
left = None
bottom = None
right = None
tmpn = 0
tmpl = []
clst = []
rle = ""

for x in cells:
tmpn += 1
tmpl.append(x)
if tmpn == 2:
clst.append(tmpl)
tmpl = []
tmpn = 0

if debug == True:
g.show(str(clst))
t.sleep(1)

for x in clst:
if x[0] < left or left == None:
left = x[0]
g.show(str(x[0]))
if x[1] < top or top == None:
top = x[1]
g.show(str(x[1]))
if x[0] > right or right == None:
right = x[0]
g.show(str(x[0]))
if x[1] > bottom or bottom == None:
bottom = x[1]
g.show(str(x[1]))

for x in range(left, right):
for y in range(top, bottom):
bFound = False
for z in clst:
if z == [x, y]:
rle += "o"
bFound = True
if z[0] == right and z[1] == y:
rle += "$" bFound = True if z[0] == right and z[1] == bottom: rle += "!" return rle if not bFound: rle += "b"  However it only returns "none" or "!", probably the last FOR isn't working... *yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. dvgrn Moderator Posts: 7585 Joined: May 17th, 2009, 11:00 pm Location: Madison, WI Contact: ### Re: Gustavo Ramos Rehermann's patterns Gustavo6046 wrote:I am fixing HRF and making a Cell list to RLE function... However it only returns "none" or "!", probably the last FOR isn't working. Is there a reason why you're worrying about writing your own function, when there's a perfectly good working one available? If you looked at the link I gave you in this message, what did you think was wrong with that code? Here's a slightly altered version of Nathaniel's code. It seems to me that this should solve your problem just fine: selection-to-clipboard-as-RLE.py: Code: Select all # RLE computation script for use with Golly. # Author: Nathaniel Johnston (nathaniel@nathanieljohnston.com), June 2009. # DMG: Refactored slightly so that the function input is a simple cell list. # This script the current selection as a test. No error checking added. # TBD: check for multistate rule, show appropriate warning. # Copies the RLE encoding of the current pattern to the clipboard import golly as g # -------------------------------------------------------------------- def chunks(l, n): for i in range(0, len(l), n): yield l[i:i+n] # -------------------------------------------------------------------- def giveRLE(clist): clist_chunks = list (chunks (clist, 2)) mcc = min(clist_chunks) rl_list = [[x[0]-mcc[0],x[1]-mcc[1]] for x in clist_chunks] rle_res = "" rle_len = 1 rl_y = rl_list[0][1] - 1 rl_x = 0 for rl_i in rl_list: if rl_i[1] == rl_y: if rl_i[0] == rl_x + 1: rle_len += 1 else: if rle_len == 1: rle_strA = "" else: rle_strA = str (rle_len) if rl_i[0] - rl_x - 1 == 1: rle_strB = "" else: rle_strB = str (rl_i[0] - rl_x - 1) rle_res = rle_res + rle_strA + "o" + rle_strB + "b" rle_len = 1 else: if rle_len == 1: rle_strA = "" else: rle_strA = str (rle_len) if rl_i[1] - rl_y == 1: rle_strB = "" else: rle_strB = str (rl_i[1] - rl_y) if rl_i[0] == 1: rle_strC = "b" elif rl_i[0] == 0: rle_strC = "" else: rle_strC = str (rl_i[0]) + "b" rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
rle_len = 1

rl_x = rl_i[0]
rl_y = rl_i[1]

if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
rle_res = rle_res[2:] + rle_strA + "o"

return rle_res+"!"

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

test_cell_list = g.getcells (g.getselrect())

RLE = giveRLE(test_cell_list)
g.setclipstr(RLE)
g.show(RLE)

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

It isn't good enough because it don't support multistate rules. I want HRF to work in multistate rules as well.

Code: Select all

# ...
def celleq(self, other):
return g.evolve(self, 0) == g.evolve(other, 0)  # Both hand sides are lists, not glife.patterns! No super() needed.

# ...

def testReaction(xpos, ypos, sli):
global found
global debug
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
Found = True
break
# ...

didn't seem to work. The right hand was just a very long list when I printed it out, even though they should be the very same...

But wait! I found out LifeHistory is the culprit! I can't remove the blue cells...

EDIT: Oooh wait, I also found out this assertion gives a error:

Code: Select all

def celleq(self, other):
return g.evolve(self, 0) == g.evolve(other, 0)  # Both hand sides are lists, not glife.patterns! No super() needed.

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])

celleq doesn't work!
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

dvgrn
Moderator
Posts: 7585
Joined: May 17th, 2009, 11:00 pm
Contact:

### Re: Gustavo Ramos Rehermann's patterns

Gustavo6046 wrote:The right hand was just a very long list when I printed it out, even though they should be the very same...

But wait! I found out LifeHistory is the culprit! I can't remove the blue cells...
Sure you can -- you just have to write specific code to ignore them. It's certainly true that they won't just magically go away.
Gustavo6046 wrote:EDIT: Oooh wait, I also found out this assertion gives a error:

Code: Select all

def celleq(self, other):
return g.evolve(self, 0) == g.evolve(other, 0)  # Both hand sides are lists, not glife.patterns! No super() needed.

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])

celleq doesn't work!
The g.evolve() trick is for making sure that the self and other cell lists don't contain any duplicates, and that the cells are in sorted order. That way you don't get any false negatives from patterns that are really the same but have their cells listed in different orders -- e.g., a block rotated by g.transform(), compared with the original block.

The assertion is failing because your two patterns are not normalized -- the top left cell isn't the same, so of course the comparison fails. I'd suggest something like this:

Code: Select all

import golly as g

def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
That just means: "move all the cells in each list so that the first live cell in the upper left corner is (0,0)."

You could normalize the lists some other way -- make the upper left cell of the bounding box be (0,0) instead, for example. That might be better for some purposes.

This definition is a little simpler to code, though. I've used it in my last several projects, and usually it doesn't cause any trouble at all.

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

IT WOOORKS

Code: Select all

import golly as g
from sys import exit
from time import sleep

found = False

herschels = []

def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])

testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")

if g.empty():
g.exit("There is no pattern to add bait!")

stillLifes = []

try:
maxgen = int(g.getstring("Which is the max generation to test for?", "300", "HRF v0.1")) + 1
except ValueError:
g.exit("Invalid number!")
if maxgen < 2:
g.exit("Null number")

while True:
4B2.2B3C$8.2B.B!  *yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. Gustavo6046 Posts: 646 Joined: December 7th, 2013, 6:26 pm Location: South of Brazil. ### Re: Gustavo Ramos Rehermann's patterns This is a experimental HRF version that inputs from a config file (.ini): Code: Select all import golly as g from sys import exit from time import sleep from ConfigParser import RawConfigParser found = False herschels = [] stillLifes = [] def celleq(self, other): ssort, osort = g.evolve(self, 0), g.evolve(other, 0) return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1]) assert celleq([0, 1, 0, 2], [0, 2, 0, 3]) testrect = g.getselrect(); if testrect == []: g.exit("Select the area where the still life is placeable!") if g.empty(): g.exit("There is no pattern to add bait!") inputconfig = g.getstring("Which file to get configuration from?") input = RawConfigParser() if input.read(InputConfig) == []: g.exit("Non-existent config file!") try: debug = input.getboolean("General", "DebugMode") maxgens = input.getint("Input", "Generations") herschels = input.get("Input", "Results").split(",") stillLifes = input.get("Input", "Baits").split(",") logfile = open(input.get("General", "LogFilename")) except ValueError: g.exit("Invalid value(s) in config!") except NoSectionError: g.exit("Invalid sections in config!") except NoOptionError: g.exit("Invalid options in config!") except IOError: g.exit("Log can't be made!") except: g.exit("Invalid config!") def logToLogfile(logged = "\n"): try: logfile.write(logged + "\n") except IOError: g.exit("Log can't be written to!") else: print "Written " + raw(logged) + " to the log!" def testReaction(xpos, ypos, sli): found = false global debug global maxgen orig = g.getcells(g.getrect()) g.putcells(stillLifes[sli], xpos, ypos) this = g.getcells(g.getrect()) oldgeneration = g.getgen() for i in range(maxgen): oldpat = g.getcells(g.getrect()) g.step() if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []: break if celleq(g.getcells(g.getrect()), herschels[sli]): found = True break g.clear(0) g.clear(1) g.setgen(oldgeneration) if found: g.putcells(this) logToLogFile("Found reaction!") else: g.putcells(orig) logToLogFile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli)) def tests(): global found for n in range(testrect[2]): for m in range(testrect[3]): for o in range(len(stillLifes)): testReaction(n + testrect[0], m + testrect[1], o) if found: return tests()  I just forgot to test it!!! ME.AM.DUMB Anyway here is a sample config file: Code: Select all [General] DebugMode=true LogFilename="hrf.log" [Input] Generations=500 Results=3o$2bo$3o!,3o$o$3o!,3o$obo$obo!,obo$obo$3o!,2o$2o!
Baits=2o$2o!,o$3o$3bo$2b2o!,bo$obo$obo$bo!,b2o$o2bo$b2o!,2b2o$bobo$bo$2o!

*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

Working HRF v0.2:

Code: Select all

import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os

herschels = []
stillLifes = []

def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])

testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")

if g.empty():
g.exit("There is no pattern to add bait!")

def parseRLEs(*args):
tmp = []
for x in args:
tmp.append(g.parse(x))
return tmp

inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")

input = cp.RawConfigParser()
g.exit("Non-existent config file!")
try:
debug = input.getboolean("General", "DebugMode")
maxgen = input.getint("Input", "Generations")
herschels = parseRLEs(*input.get("Input", "Results").split(","))
stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
logfile = open(input.get("General", "LogFilename"), "w")
outdir = input.get("General", "OutputDir")

except ValueError:
g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
g.exit("Invalid sections in config!")
except cp.NoOptionError:
g.exit("Invalid options in config!")

def logToLogfile(logged = "\n"):
try:
logfile.write(logged + "\n")
except IOError:
g.exit("Log can't be written to!")

results = 0

this = []

def ensure_dir(f):
if not os.path.exists(f):
os.makedirs(f)

ensure_dir(outdir)

def testReaction(xpos, ypos, sli):
found = False
global debug
global maxgen
global results
global this
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
found = True
break
g.clear(0)
g.clear(1)
g.setgen(oldgeneration)
if found:
results += 1
g.putcells(orig)
logToLogfile("Found reaction!")
output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
output.write(str(this))
output.close()
else:
g.putcells(orig)
logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))

def tests():
global found
for n in range(testrect[2]):
for m in range(testrect[3]):
for o in range(len(stillLifes)):
testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)

Also this is the new INI specification:

Code: Select all

[General]
DebugMode=<whether debug mode is on>
LogFilename=<filename of log>
OutputDir=<name of directory to save outputs to>

[Input]
Generations=<max number of generations in each test>
Results=<desired result RLEs separated by comma and no space>
Baits=<bait still life RLEs separated by comma and no space>

*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

I tried inserting Nathaniel's RLE script but it gives me a "int object has no attribute '__getitem__'" error, which is omfg very freaking weird. Maybe it's for older Python versions?
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

dvgrn
Moderator
Posts: 7585
Joined: May 17th, 2009, 11:00 pm
Contact:

### Re: Gustavo Ramos Rehermann's patterns

Gustavo6046 wrote:I tried inserting Nathaniel's RLE script but it gives me a "int object has no attribute '__getitem__'" error, which is omfg very freaking weird. Maybe it's for older Python versions?
No, it works fine with the latest Python. Do you mean you tried using the version of Nathaniel's script that I just re-posted? My version of the function had a few new lines of code at the beginning, which changed the function's expected input so it can handle a regular flat cell list.

Or did you go back and get Nathaniel's original script, and then try to pass it a regular flat cell list? I would imagine you might well get some mysterious error along those lines, in that case. The error is just saying:

Your code wants this data to be a list (or something with multiple pieces, anyway).
But this data that I actually have is not a list, it's just a plain old number.

I haven't tried it, but you might get something similar if you try to pass in a multistate cell list. If you want to handle that case, you need to test for it specifically, set the chunk size to 3 if necessary, throw out any state-2 blue cells, and so forth.

Or keep things simple and just do the conversion to a single-state rule before you start, using some code along the lines of ToLife.py.

Gustavo6046
Posts: 646
Joined: December 7th, 2013, 6:26 pm
Location: South of Brazil.

### Re: Gustavo Ramos Rehermann's patterns

OK, I'll use your variant them.

But I guess it's later, because I have YET ANOTHER error in my hands: (oh crap)

Code: Select all

import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os, shutil

herschels = []
stillLifes = []

def celleq(self, other):
ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])

testrect = g.getselrect();
if testrect == []:
g.exit("Select the area where the still life is placeable!")

if g.empty():
g.exit("There is no pattern to add bait!")

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

def giveRLE(rl_list):
rle_res = ""
rle_len = 1
rl_y = rl_list[0][1] - 1
rl_x = 0
for rl_i in rl_list:
if rl_i[1] == rl_y:
if rl_i[0] == rl_x + 1:
rle_len += 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[0] - rl_x - 1 == 1: rle_strB = ""
else: rle_strB = str (rl_i[0] - rl_x - 1)

rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
rle_len = 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[1] - rl_y == 1: rle_strB = ""
else: rle_strB = str (rl_i[1] - rl_y)
if rl_i[0] == 1: rle_strC = "b"
elif rl_i[0] == 0: rle_strC = ""
else: rle_strC = str (rl_i[0]) + "b"

rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC rle_len = 1 rl_x = rl_i[0] rl_y = rl_i[1] if rle_len == 1: rle_strA = "" else: rle_strA = str (rle_len) rle_res = rle_res[2:] + rle_strA + "o" return rle_res def parseRLEs(*args): tmp = [] for x in args: tmp.append(g.parse(x)) return tmp inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2") input = cp.RawConfigParser() if input.read(inputconfig) == []: g.exit("Non-existent config file!") try: debug = input.getboolean("General", "DebugMode") maxgen = input.getint("Input", "Generations") herschels = parseRLEs(*input.get("Input", "Results").split(",")) stillLifes = parseRLEs(*input.get("Input", "Baits").split(",")) logfile = open(input.get("General", "LogFilename"), "w") outdir = input.get("General", "OutputDir") except ValueError: g.exit("Invalid value(s) in config!") except cp.NoSectionError: g.exit("Invalid sections in config!") except cp.NoOptionError: g.exit("Invalid options in config!") def logToLogfile(logged = "\n"): try: logfile.write(logged + "\n") except IOError: g.exit("Log can't be written to!") results = 0 this = [] def ensure_dir(f): if not os.path.exists(f): os.makedirs(f) if os.path.isdir(outdir): shutil.rmtree(outdir) ensure_dir(outdir) def testReaction(xpos, ypos, sli): found = False global debug global maxgen global results global this orig = g.getcells(g.getrect()) g.putcells(stillLifes[sli], xpos, ypos) this = g.getcells(g.getrect()) oldgeneration = g.getgen() for i in range(maxgen): oldpat = g.getcells(g.getrect()) g.step() if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []: break if celleq(g.getcells(g.getrect()), herschels[sli]): found = True break g.clear(0) g.clear(1) g.setgen(oldgeneration) if found: results += 1 g.putcells(orig) logToLogfile("Found reaction!") output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w") output.write(giveRLE(g.evolve(this, 0))) output.close() else: g.putcells(orig) logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli)) def tests(): global found for n in range(testrect[2]): for m in range(testrect[3]): for o in range(len(stillLifes)): testReaction(n + testrect[0], m + testrect[1], o) tests() logfile.close() g.clear(1) g.clear(0) g.putcells(this)  Yes, that's quite a bit of code. It will most probably be hard to debug. The error is "list index out of range" at line 126. Sometimes it will give some "Access Negated" errors but nothing that worries. I wonder how to ignore a exception... *yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. Scorbie Posts: 1538 Joined: December 7th, 2013, 1:05 am ### Re: Gustavo Ramos Rehermann's patterns I can see that your python is improving every version. This seems to be good practice for you. Gustavo6046 wrote:The error is "list index out of range" at line 126. Line 126 is a call to the function "celleq", and for that line to raise an error, the function body of celleq may be a problem? I would recommend posting the whole error message (unless it's too long) so that people would have a better idea of the problem. Anyway, as there are no more information available, I would have to assume that the error was raised inside the "celleq" function body. For that to raise an IndexError, line 12: Code: Select all  return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1]) should be a problem when osort or ssort has less than 2 items. (Which would be when osort or ssort is an empty cell list.) @Gustavo You **did** fix that prior bug before you added functionality, right? Extending a not-working program seems to be a little nonsense, and would create a bigger not-working program instead of a small but working one. @dvgrn By the way, does g.evolve(clist, 0) sort all the coordinates? EDIT: Thanks for the explanation. (it's in page 38) Last edited by Scorbie on January 23rd, 2016, 4:10 am, edited 1 time in total. Best wishes to you! - Scorbie Gustavo6046 Posts: 646 Joined: December 7th, 2013, 6:26 pm Location: South of Brazil. ### Re: Gustavo Ramos Rehermann's patterns Thanks! Just fixed it. It works fine for a few cycles, then crashes because of a line 141 IndexError: Code: Select all import golly as g from sys import exit from time import sleep import ConfigParser as cp import os, glob herschels = [] stillLifes = [] def celleq(self, other): if self != [] or other != []: ssort, osort = g.evolve(self, 0), g.evolve(other, 0) return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1]) elif self == other: return true else: return false assert celleq([0, 1, 0, 2], [0, 2, 0, 3]) testrect = g.getselrect(); if testrect == []: g.exit("Select the area where the still life is placeable!") if g.empty(): g.exit("There is no pattern to add bait!") def chunks(l, n): for i in range(0, len(l), n): yield l[i:i+n] def parseRLEs(*args): tmp = [] for x in args: tmp.append(g.parse(x)) return tmp def chunks(l, n): for i in range(0, len(l), n): yield l[i:i+n] def giveRLE(clist): clist_chunks = list (chunks (clist, 2)) mcc = min(clist_chunks) rl_list = [[x[0]-mcc[0],x[1]-mcc[1]] for x in clist_chunks] rle_res = "" rle_len = 1 rl_y = rl_list[0][1] - 1 rl_x = 0 for rl_i in rl_list: if rl_i[1] == rl_y: if rl_i[0] == rl_x + 1: rle_len += 1 else: if rle_len == 1: rle_strA = "" else: rle_strA = str (rle_len) if rl_i[0] - rl_x - 1 == 1: rle_strB = "" else: rle_strB = str (rl_i[0] - rl_x - 1) rle_res = rle_res + rle_strA + "o" + rle_strB + "b" rle_len = 1 else: if rle_len == 1: rle_strA = "" else: rle_strA = str (rle_len) if rl_i[1] - rl_y == 1: rle_strB = "" else: rle_strB = str (rl_i[1] - rl_y) if rl_i[0] == 1: rle_strC = "b" elif rl_i[0] == 0: rle_strC = "" else: rle_strC = str (rl_i[0]) + "b" rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
rle_len = 1

rl_x = rl_i[0]
rl_y = rl_i[1]

if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
rle_res = rle_res[2:] + rle_strA + "o"

return rle_res+"!"

inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")

input = cp.RawConfigParser()
g.exit("Non-existent config file!")
try:
debug = input.getboolean("General", "DebugMode")
maxgen = input.getint("Input", "Generations")
herschels = parseRLEs(*input.get("Input", "Results").split(","))
stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
logfile = open(input.get("General", "LogFilename"), "w")
outdir = input.get("General", "OutputDir")

except ValueError:
g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
g.exit("Invalid sections in config!")
except cp.NoOptionError:
g.exit("Invalid options in config!")

def logToLogfile(logged = "\n"):
try:
logfile.write(logged + "\n")
except IOError:
g.exit("Log can't be written to!")

results = 0

this = []

def ensure_dir(f):
if not os.path.exists(f):
os.makedirs(f)
os.chmod(f)

def remove_folder_content(f):
filelist = glob.glob(f + "\\*.*")
for x in filelist:
os.remove(x)

remove_folder_content(outdir)
ensure_dir(outdir)

def testReaction(xpos, ypos, sli):
found = False
global debug
global maxgen
global results
global this
orig = g.getcells(g.getrect())
g.putcells(stillLifes[sli], xpos, ypos)
this = g.getcells(g.getrect())
oldgeneration = g.getgen()
for i in range(maxgen):
oldpat = g.getcells(g.getrect())
g.step()
if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
break
if celleq(g.getcells(g.getrect()), herschels[sli]):
found = True
break
g.clear(0)
g.clear(1)
g.setgen(oldgeneration)
if found:
results += 1
g.putcells(orig)
logToLogfile("Found reaction!")
output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
output.write(giveRLE(g.evolve(this, 0)))
output.close()
else:
g.putcells(orig)
logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))

def tests():
global found
for n in range(testrect[2]):
for m in range(testrect[3]):
for o in range(len(stillLifes)):
testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)

*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times.

Scorbie
Posts: 1538
Joined: December 7th, 2013, 1:05 am

### Re: Gustavo Ramos Rehermann's patterns

Gustavo6046 wrote:It works fine for a few cycles, then crashes because of a line 141 IndexError:
Hmm, it's the same function call again and I'm not sure what's the problem... Good luck. Crashes leave stack traces, so I guess that would be easier to fix than subtle bugs.
Anyway, as I said before,
I would recommend posting the whole error message (unless it's too long) so that people would have a better idea of the problem.
If a Golly python script crashes, I think it gives the um... call trace(?) with a popup window. Copy that message and paste it here next time.
Best wishes to you! - Scorbie