The Quest For A 6x6 Methuselah In LeapLife

A forum for topics that don't fit elsewhere. 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. Forum rules still apply.
Post Reply
Hunting
Posts: 4401
Joined: September 11th, 2017, 2:54 am

The Quest For A 6x6 Methuselah In LeapLife

Post by Hunting » November 16th, 2020, 10:13 am

Few efforts have been put into methuselah searching in LeapLife, and the longest-living known methuselah* is only 246 generations. So let's see how long-lived can LeapLife patterns be.

I randomly searched 16x16 soups for methuselahs before, but it did not work too well - the best I got is only around 300 generations. I concluded that larger soups don't necessarily live longer in LeapLife (it might be also interesting to study this, but I'll do it later.) So let's start with 6x6, which I don't think will be enumerated in the foreseeable future (that's 68,719,476,736 different patterns - if some kind of apgsearch modification can go through 1000 per second, it's around 800 days. I don't know how efficient will the potential modification be though.)

Hand searchers and program searchers, come on and collabrate!

Note: I know MCPS is the correct way to measure the size of a methuselah and bounding box is out of fashion but bounding box is also more convenient and machine-friendly, so I'll use it here.

Note 2: I once enumerated all 4x5 methuselahs with a PlutoniumSearch modification, but it's so slow that it took like 1 or 2 hours. I'm going to do 5x5 soon, though it likely will take several days.

*from a reasonably small pattern. I think there are a few 4x4 predecessors too, but I'm too lazy to find them.

Hunting
Posts: 4401
Joined: September 11th, 2017, 2:54 am

Re: The Quest For A 6x6 Methuselah In LeapLife

Post by Hunting » November 16th, 2020, 10:20 am

...I found some ancient results. How many generations is this?

Code: Select all

x = 6, y = 6, rule = B2n3/S23-q
b3o$b2o$3bobo$3o2bo$3bobo$2o3bo!

User avatar
Moosey
Posts: 4315
Joined: January 27th, 2019, 5:54 pm
Location: here
Contact:

Re: The Quest For A 6x6 Methuselah In LeapLife

Post by Moosey » November 16th, 2020, 2:51 pm

Hunting wrote:
November 16th, 2020, 10:20 am
...I found some ancient results. How many generations is this?

Code: Select all

x = 6, y = 6, rule = B2n3/S23-q
b3o$b2o$3bobo$3o2bo$3bobo$2o3bo!
395
not active here but active on discord

loves estradiol valerate

Hunting
Posts: 4401
Joined: September 11th, 2017, 2:54 am

Re: The Quest For A 6x6 Methuselah In LeapLife

Post by Hunting » November 17th, 2020, 7:03 am

Moosey wrote:
November 16th, 2020, 2:51 pm
Hunting wrote:
November 16th, 2020, 10:20 am
...I found some ancient results. How many generations is this?

Code: Select all

x = 6, y = 6, rule = B2n3/S23-q
b3o$b2o$3bobo$3o2bo$3bobo$2o3bo!
395
Thanks.

I ran a 6x6 random soup search again. Nothing over 395, but this 11-cell 4x6 diehard is extremely impressive:

Code: Select all

x = 4, y = 6, rule = B2n3/S23-q
b3o$3bo$2b2o2$3o$2b2o!
EDIT: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Code: Select all

x = 6, y = 6, rule = B2n3/S23-q
3b2o$2b2o$bo2bo$2o3bo$4bo$2bobo!
at 649 generations. Can someone run LLS to find predecessors?

Also here's a 5x6 methuselah:

Code: Select all

x = 6, y = 5, rule = B2n3/S23-q
o3bo$2o3bo$4bo$o2bobo$2bob2o!

Hunting
Posts: 4401
Joined: September 11th, 2017, 2:54 am

Re: The Quest For A 6x6 Methuselah In LeapLife

Post by Hunting » December 3rd, 2020, 2:26 am

Hunting wrote:
November 17th, 2020, 7:03 am
Can someone run LLS to find predecessors?
Since everyone ignored my request, 650 generations:

Code: Select all

x = 6, y = 6, rule = B2n3/S23-q
bobobo$2b2o$4bo$2obo$b5o$obo!
Also 5x7 predecessor with only 13 cells:

Code: Select all

x = 5, y = 7, rule = B2n3/S23-q
3b2o$b2o$o2b2o$obo$o3bo$2bo$2bo!
6x7 grandparent:

Code: Select all

x = 6, y = 7, rule = B2n3/S23-q
o2b2o$3bo$obo2bo$3o2bo2$bobo$2bo!

Dylan Chen
Posts: 114
Joined: March 27th, 2020, 8:07 am
Contact:

Re: The Quest For A 6x6 Methuselah In LeapLife

Post by Dylan Chen » December 4th, 2020, 7:52 pm

I'd like to contribute.But how?
Tools should not be the limit.
Whether your obstacle is a script, an stdin, or Linux environment computing resouces.
check New rules thread for help.

goldenratio
Posts: 295
Joined: July 26th, 2020, 10:39 pm
Location: Texas, USA

Re: The Quest For A 6x6 Methuselah In LeapLife

Post by goldenratio » December 4th, 2020, 10:29 pm

Tried to make a script for this a couple weeks ago but it doesn't work

Code: Select all

import golly as g
# Initialization
w = int(g.getstring("Width:"))
h = int(g.getstring("Height:"))
count = int(g.getstring("Soup count:"))
greatestrun = 0
gens = 0
# Set the maximum stabilization time higher if needed
maxgens = 4800
# periodcheck = LCM of periods for most common oscillators/spaceships in the rule
periodcheck = 12
pop1 = 0
pop2 = 0
pop3 = 0
soup = []
keep_running = True
g.select([0, 0, w, h])
g.setbase(8)
g.setstep(4)
# Running the specified number of soups
for i in range(count):
    g.randfill(50)
    g.run(periodcheck)
    pop3 = int(g.getpop())
    g.run(periodcheck)
    pop2 = int(g.getpop())
    g.run(periodcheck)
    pop1 = int(g.getpop())
    while keep_running == True:
        # Checking if population is cyclic with period periodcheck
        if ((pop1 == pop2) and (pop2 == pop3)):
            keep_running = False
            gens = int(g.getgen())
            # Checking if soup breaks current record and recording soup if it does
            if (gens > greatestrun):
                g.reset()
                soup = g.getcells([0, 0, w, h])
                greatestrun = gens
        # Checking if soup reached maximum number of generations
        if (g.getgen() > maxgens):
            keep_running = False
        # Run and update the three most recent populations
        g.run(periodcheck)
        pop3 = pop2
        pop2 = pop1
        pop1 = int(g.getpop())
    keep_running = True
    g.reset()
    # Only showing every tenth soup generated
    if (i % 10) == 0:
        g.update()
    if (i % 100) == 0:
        g.show(str(i) + " soups completed; current record = " + str(greatestrun))
# Pasting record soup into new pattern
g.new("")
g.putcells(soup)
You could use this less complicated (working) script to find largest non-infinite-growth final populations but that often doesn't find the longest lived methuselah

Code: Select all

import golly as g
w = int(g.getstring("Width:"))
h = int(g.getstring("Height:"))
count = int(g.getstring("Soup count:"))
greatestpop = 0;
soup = []
g.select([0, 0, w, h])
g.setbase(8)
g.setstep(4)
for i in range(count):
    g.randfill(50)
    g.run(16384)
    pop1 = int(g.getpop())
    g.run(512)
    pop2 = int(g.getpop())
    g.reset()
    if pop2 < pop1 + 50:
        if pop1 > greatestpop:
            greatestpop = pop1
            soup = g.getcells([0, 0, w, h])
    if (i % 10) == 0:
        g.update()
    if (i % 100) == 0:
        g.show(str(i) + " soups completed.")
g.new("")
g.putcells(soup)
Oscillator discussion is boring me out. I'll return when the cgol community switches to something else.

Me on LifeWiki

Hunting
Posts: 4401
Joined: September 11th, 2017, 2:54 am

Re: The Quest For A 6x6 Methuselah In LeapLife

Post by Hunting » December 5th, 2020, 3:46 am

goldenratio wrote:
December 4th, 2020, 10:29 pm
Tried to make a script for this a couple weeks ago but it doesn't work

Code: Select all

import golly as g
# Initialization
w = int(g.getstring("Width:"))
h = int(g.getstring("Height:"))
count = int(g.getstring("Soup count:"))
greatestrun = 0
gens = 0
# Set the maximum stabilization time higher if needed
maxgens = 4800
# periodcheck = LCM of periods for most common oscillators/spaceships in the rule
periodcheck = 12
pop1 = 0
pop2 = 0
pop3 = 0
soup = []
keep_running = True
g.select([0, 0, w, h])
g.setbase(8)
g.setstep(4)
# Running the specified number of soups
for i in range(count):
    g.randfill(50)
    g.run(periodcheck)
    pop3 = int(g.getpop())
    g.run(periodcheck)
    pop2 = int(g.getpop())
    g.run(periodcheck)
    pop1 = int(g.getpop())
    while keep_running == True:
        # Checking if population is cyclic with period periodcheck
        if ((pop1 == pop2) and (pop2 == pop3)):
            keep_running = False
            gens = int(g.getgen())
            # Checking if soup breaks current record and recording soup if it does
            if (gens > greatestrun):
                g.reset()
                soup = g.getcells([0, 0, w, h])
                greatestrun = gens
        # Checking if soup reached maximum number of generations
        if (g.getgen() > maxgens):
            keep_running = False
        # Run and update the three most recent populations
        g.run(periodcheck)
        pop3 = pop2
        pop2 = pop1
        pop1 = int(g.getpop())
    keep_running = True
    g.reset()
    # Only showing every tenth soup generated
    if (i % 10) == 0:
        g.update()
    if (i % 100) == 0:
        g.show(str(i) + " soups completed; current record = " + str(greatestrun))
# Pasting record soup into new pattern
g.new("")
g.putcells(soup)
You could use this less complicated (working) script to find largest non-infinite-growth final populations but that often doesn't find the longest lived methuselah

Code: Select all

import golly as g
w = int(g.getstring("Width:"))
h = int(g.getstring("Height:"))
count = int(g.getstring("Soup count:"))
greatestpop = 0;
soup = []
g.select([0, 0, w, h])
g.setbase(8)
g.setstep(4)
for i in range(count):
    g.randfill(50)
    g.run(16384)
    pop1 = int(g.getpop())
    g.run(512)
    pop2 = int(g.getpop())
    g.reset()
    if pop2 < pop1 + 50:
        if pop1 > greatestpop:
            greatestpop = pop1
            soup = g.getcells([0, 0, w, h])
    if (i % 10) == 0:
        g.update()
    if (i % 100) == 0:
        g.show(str(i) + " soups completed.")
g.new("")
g.putcells(soup)
I'm using this:

Code: Select all

import golly as g

# Parameters
bx = 6
by = 6
min_lifespan = 390
min_lifespan_dh = 80

# Do not change this
patt_count = 0
meth_count = 0

def random_soup():
	global bx, by
	while 1:
		g.new("Looking for methuselahs...")
		g.select([0, 0, bx, by])
		g.randfill(37)
		run_patt(g.getcells(g.getrect()))


def kill_gliders():
	if g.empty():
		return
	pat = g.getcells(g.getrect())
	glider_phase_1 = 1244187411
	glider_phase_2 = -1688977488
	for i in range(-1, 2):
		for j in range(-1, 2):
			for k in range(-1, 2):
				for l in range(-1, 2):
					# g.warn(' '.join([str(i), str(j), str(k), str(l)]))
					if (i or j) and (not (i and j)) and (k or l) and (not (k and l)) and (not (i and k)) and (not (j and l)):
						newpat = g.transform(pat, 0, 0, i, j, k, l)
						g.addlayer()
						g.setname("Glider-killing")
						g.putcells(newpat)
						g.select([g.getrect()[0], g.getrect()[1], 3, 3])
						#g.warn("a")
						c = g.hash([g.getrect()[0], g.getrect()[1], 3, 3])
						if glider_phase_1 == c or glider_phase_2 == c:
							g.select([g.getrect()[0], g.getrect()[1], 3, 3])
							g.clear(0)
							g.update()
							#g.warn("a")
							newpat = g.getcells(g.getrect())
							for loop in range(3):
								newpat = g.transform(newpat, 0, 0, i, j, k, l)
							g.dellayer()
							g.new("Looking for methuselahs...")
							g.putcells(newpat)
							continue
						#g.warn("a")
						g.dellayer()

def run_patt(patt):
	global patt_count, meth_count, min_lifespan
	g.new("Looking for methuselahs...")
	g.reset()
	g.update()
	patt_count += 1
	#patt = g.parse(known_cells + "!")
	#g.note(known_cells[1:] + "!")
	g.putcells(patt)
	g.update()
	hashlist = {}
	while 1:
		if g.empty():
			if int(g.getgen()) > min_lifespan_dh:
				meth_count += 1
				newlifespan = int(g.getgen())
				g.new("Saving methuselah")
				g.putcells(patt)
				g.save("diehard-" + str(newlifespan) + ".rle", "rle")
				g.update()
				#max_final_pop = newpop
			break
		if g.hash(g.getrect()) in hashlist:
			if hashlist[g.hash(g.getrect())] > min_lifespan:
				meth_count += 1
				newlifespan = hashlist[g.hash(g.getrect())]
				g.new("Saving methuselah")
				g.putcells(patt)
				g.save("methuselah-" + str(newlifespan) + ".rle", "rle")
				g.update()
				#max_final_pop = newpop
			break
		else:
			hashlist[g.hash(g.getrect())] = int(g.getgen())
			g.run(1)
		"""
		except:
			# Pattern dies
			if int(g.getgen()) > min_lifespan:
				meth_count += 1
				newlifespan = int(g.getgen())
				g.new("Saving methuselah")
				g.putcells(patt)
				try:
					g.save("diehard-" + str(newlifespan) + ".rle", "rle")
				except:
					pass
				g.update()
				#max_final_pop = newpop
			break"""
		if int(g.getgen()) % 60 == 59:
			kill_gliders()
	#g.warn(str(hashlist))
	g.show(str(patt_count) + " patterns tested, " + str(meth_count) + " methuselahs found")

g.autoupdate(True)
random_soup()
#run_patt("$3o$2o$o!")
Reports tons of false positives when more than one glider is emitted/a lepa is emitted/an LWSS is emitted/whatever, but in leaplife they are not too common. after around 2h, I only got like 20 of those.

Post Reply