Page 1 of 1

The Quest For A 6x6 Methuselah In LeapLife

Posted: November 16th, 2020, 10:13 am
by Hunting
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.

Re: The Quest For A 6x6 Methuselah In LeapLife

Posted: November 16th, 2020, 10:20 am
by Hunting
...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!

Re: The Quest For A 6x6 Methuselah In LeapLife

Posted: November 16th, 2020, 2:51 pm
by Moosey
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

Re: The Quest For A 6x6 Methuselah In LeapLife

Posted: November 17th, 2020, 7:03 am
by Hunting
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!

Re: The Quest For A 6x6 Methuselah In LeapLife

Posted: December 3rd, 2020, 2:26 am
by Hunting
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!

Re: The Quest For A 6x6 Methuselah In LeapLife

Posted: December 4th, 2020, 7:52 pm
by Dylan Chen
I'd like to contribute.But how?

Re: The Quest For A 6x6 Methuselah In LeapLife

Posted: December 4th, 2020, 10:29 pm
by goldenratio
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)

Re: The Quest For A 6x6 Methuselah In LeapLife

Posted: December 5th, 2020, 3:46 am
by Hunting
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.