Maximum lifespan on torus

For discussion of specific patterns or specific families of patterns in Conway's Game of Life, both newly-discovered and well-known.
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Maximum lifespan on torus

Post by Vort »

Hello.
While observing Game of Life simulations on torus, I noticed they usually stabilize relatively quickly.
For example, for 20x20 torus, amount of possible patterns is 2^400, but I was able to achieve lifespan of only 2292:

Code: Select all

x = 20, y = 20, rule = B3/S23:T20,20
18b2o$bo10bo$3bo2b2o2b2o$obobo$2bo2bob2ob2o6bo$2b2o15bo$3b2obo7b4o$13b
o3bobo$4b2obobo5b3obo$11b2obo2bo$bobob3o2bo3bo$7bo3bo$o4bo3bo7bo$bobob
o4bo4bo$o4bo3bo4bo$2bo4bo5bo5bo$bo6bo2bo$6bobo5bo$4o13bobo$2bo7bob2o4b
2o!
I expect it is possible to achieve much higher result, but how?
I got idea of using 20x20 torus from this topic, but maybe 20x20 is not enough and possibilities of getting much higher lifetimes open up only in larger worlds (100x100 for example)?
User avatar
tommyaweosme
Posts: 1581
Joined: January 15th, 2024, 9:37 am

Re: Maximum lifespan on torus

Post by tommyaweosme »

very high lifespan

Code: Select all

x = 438, y = 100, rule = B3/S23:T350,100
7$73b3o11b3o253b3o11b3o$72bo3bo9bo3bo251bo3bo9bo3bo$71b2o4bo7bo4b2o
249b2o4bo7bo4b2o$70bobob2ob2o5b2ob2obobo247bobob2ob2o5b2ob2obobo$69b2o
bo4bob2ob2obo4bob2o245b2obo4bob2ob2obo4bob2o$68bo4bo3bo2bobo2bo3bo4bo
243bo4bo3bo2bobo2bo3bo4bo$80bobo267bobo$68b2o7b2obobob2o7b2o243b2o7b2o
bobob2o7b2o$80bobo267bobo$74b3o9b3o255b3o9b3o$74bo9bo3bo255bo3bo9bo$
79b3o4bobo255bobo4b3o$73b2o4bo2bo267bo2bo4b2o$79bo273bo$79bo3bo265bo3b
o$79bo3bo265bo3bo$79bo273bo$80bobo267bobo!
[[ STEP 17 ]]
credit to d/dx for this pattern
here's the gosper glider gun

Code: Select all

#R life
24bo$22bobo$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o$2o8bo3bob2o4b
obo$10bo5bo7bo$11bo3bo$12b2o!
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

very high lifespan
With criterion from this page: "The time when a pattern is considered to have stabilized is commonly agreed upon to be the first generation such that the pattern can be resolved into still lifes, oscillators and escaping spaceships", this pattern becomes oscillator at generation = 509. Generation 509 is equal to generation 10109.
User avatar
b-engine
Posts: 3762
Joined: October 26th, 2023, 4:11 am
Location: Somewhere on where Earth At
Contact:

Re: Maximum lifespan on torus

Post by b-engine »

It's trivial to place a glider at the front of a slightly slower spaceship in a torus, but the chasing spaceships only survive for 101 generations until they collides and eventually stabilize at generation 638:

Code: Select all

x = 23, y = 23, rule = B3/S23:T23,23
20b2o$20b2o$19bo2bo$16b2obo2bo$22bo$14b2o3bo2bo$14b2o5bo$15bob5o$8b3o
5bo$8bo$9bo$13b3o$13bo$11b2o$5b2o4bo$5b3o3bo$3bo4bo$3bo3bo$7bo$2b2obo
bo$2o5bo$2o4b2o$2b4o!
This lives longer, with lifespan of 4267 in trade of larger torus:

Code: Select all

x = 23, y = 23, rule = B3/S23:T100,100
20b2o$20b2o$19bo2bo$16b2obo2bo$22bo$14b2o3bo2bo$8b3o3b2o5bo$8bo6bob5o
$9bo6bo3$13b3o$13bo$11b2o$5b2o4bo$5b3o3bo$3bo4bo$3bo3bo$7bo$2b2obobo$
2o5bo$2o4b2o$2b4o!
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

b-engine wrote: May 17th, 2024, 3:05 am It's trivial to place a glider at the front of a slightly slower spaceship in a torus
...
This lives longer, with lifespan of 4267 in trade of larger torus:
Nice idea.
For comparison, here is result from random search on 80x80 torus, lifespan = 9419.
Looks like more live cells means more possibilities.
But I think engineered solutions will win eventually.

Code: Select all

x = 80, y = 80, rule = B3/S23:T80,80
2o2b2o11b2ob4o2b2obo8bo2bo5bo2bobob2o2bo2b5o4bobo4bo$b5ob3o3bobo3bo4b
3o7bo2b3o3bob2o8bo3bo2bo3bob2o2bob2o$3bo3bo2bo2b2ob2ob2o3b2ob2o2bo2bob
obo3bo3b3o8b2obo3b2o8bob2o$7b2o2bo3bob2o3bo5b3o6b2o4bo3b3obobob3o7bob
2obobo3bo$7bo4bo9bo3bo3bo5b3obo8bo2bo2b3obo3b3o4bo2bobo3bo$6bob2o2b2ob
2o2bo6bob2o2bobo6b2o3b5obo2b3obobobobo3bobo2bob4o$o5bo2bob2obob2o5b3o
6b3o3b2obo2bo2bo3bo3bo7b5ob2obo3bobo$o5bo6b4o10bo2bo2bobobobo2bo5b2o3b
2o3bob2obo10bo$2o2b3o2bob2o3bob2o2bo3b2o3bobo4b2obo3bo7b6obo4bo2b3o2bo
4bo$bobo7bo7bo5b2o3bobo2bo5bo2bo2b4o2bo8b3ob2o2bo3bobo$3bo5bo6bo5b2obo
bobo2bo6bob2o4bobob2o4b2obo3bo2b2ob3obo$o6b2ob2ob2ob2o2bo3b3o4bo2bobo
3b3o4b5obo5b2obob2o11bobo$4b2o4bo2bo6b3o4bo3b2o3bo2bo2b2ob2o6bobo5bo4b
2ob2o2bo3b3o$obo3bo4b2o9bo2bo3bo4bo3bo6bobobo4bo3bobo3b2o7bo2b3o$2b4o
2bo2bo2bo4bo7bo10bobo5bobo3bo2b3o2bobobo3b3o4b2o2bo$bo4bobo2bo13bobobo
bo5bo2b2o7bo3bobob2o2bo5bobo7bo$2bo2bob2obo3b3o2b2o13bo2b2o3b2obo4bob
2obo2b2obo4bo2b3o6b2o$3bo2bo3b7o3b7o2bo2b4ob2o5bo4bo2b2o2bob2o5b3o6bo
3b2o$2bo4b3o2bobo3bo7bo2bo5bob2o5b2o7b2obob2o2bo2bob2o5b2o2bo$6b2o2bob
2o3bobo2bo4b3obo3bo2bob3o4bo4b2o2bo5bo10bobo$bo3b2o5b2ob2o7bo3bo3bo3bo
6b2o5bo2bo3bobo4bo5bo3bobob2o$4bobo2bo2bob2obo2b4o4bo3b2o3b2o5bo2bo10b
o4bo4b2o2bo$3bo2bo3bob2o6bobo4b4o2b2obo2bo4b2o7bo5bo3bobo2b2ob2ob2o$4b
3o2bob2obob2obobo8bo3bo2bo4bobobo4bo4bo3bo4bo2b5obo4bo$b3o2b3o5bo3b3o
5b2o7b2o11bo2bobobo2b2o3bo2bo2b3ob2obo$b2o3b2o2bo3b2obo4b3o3bob2o10bob
ob4o2b2obobobo2b2o2bobob2o6bo$o5b2obo2bo4b4o5b2o4bob2ob3ob2o4bobo2bo5b
obo4bo10bo2bo$bobob3obob2o7b2o3bob2o6bo5bobo2bob2o8bobob2o2b3o3bo2bobo
$2b3obob2o2b2ob2o3bo2b2o6b2o2bobobo2b2obo4bo3bobo4bo2bo2bobo4bo4bo$o2b
o2bo3bob2o8b5o2b2o9b5o5b2o4b3o7bo4bo2bob3o$4b2o7bo2bo4bob4o7b2o3bo2b2o
11bo5bo6bo2bo3b2ob2o$bobo3b2o2bo8bo3b2obob2o3bo3bo4bob3obo3b3obobobo5b
o2bo$2bo4bo2b2o3bobo3b6o7bob3o3bo6bobo4bobo3bo2b3ob2obo6bo$o10b2obo3b
2o4b4o4bob3o2b2o11b2o3bo9b2o2b2obobo2bo$b4obobo3b2o2bobobo7bobobo2bo7b
o2b2o3bob3o2b3o7bo4b3obobo$5bob2o2b3o2bo3bo7bo2bo4b2o4bo4bobobo3bobo2b
2ob2obo2bobo2bobo2bo$2b3o2b2o5bo3b5obob2o2bobo3bobo2b2obo2bo2b3o6bo3bo
3b2o6bo2bo$o2bo2bo3b3ob2obo4bobo3bo4b2obo3b2ob3o7bo5bo2bobo6bo3b2o2bo$
o4bo2bo5b2ob2o3b2ob2o3bo5b5o6bo3bobo5bo2bo2bo3b2o2b2obo2bo$2b5obo4b3o
7b2obo5bo2bobo5bo4b4ob2ob2o4bo4bobo5bo2bo$6b3o3bo2bo2b2o2bo2bobo2b2o3b
4ob3obo9b3ob2obo4bobo5b2o3bo$3b2o5bobo2bo2bo4bob2o6bobo2b5ob2obo4bo12b
2obo2bob2o$b3o7bobob2ob2o3bobob4o2bo8bo3b3obo5b3ob3obo4bo3b4ob2o$3bo2b
o3b2o6b3o2b2obo2b2ob2o2bo7bo2bo4b2o5b2obo3bo3bo$bo2bo2b4obo4bo4bo3bob
2o3b3o2b3obo6b2o5b3obo2bobo8bob2o$2bo4bo2bob2o2b3obo2bobobo2bo2bo4b2ob
3o7bo5b2o2bo3b2ob2ob3o2bob2o$bo3bo10bo7b3obobo2bo4b2o2bo2bo6bo2bo4bo2b
2o4bo3b4o$2b3obo7bo2bo4bobobo2bo8bo3bo5bo2b4obob3obo2bobo3b2obo4bo$bob
o8bo2bo3b2ob2o3b2obo2bobobobobo2bo4b3o2b3ob3o2bo4b2o7b2o$bo2bo2b3obo2b
2o2b3ob2o5b2o2bo9bo7b2o3bo3b2o3bo2b3ob2o2b2obo$2bo2bo9b5obobo2b2obobob
2obobo3bo3b3o2b2obo3bob2o5bo2bo2bo2b2o$3bo7bo7b3o2b3obob2o4bo2bob2o2bo
bob2obo3b2o2b2o7b3o7bo$ob3ob2ob3o12bo9b3obo3b2o5b2obo2b2obo3bobo2b2ob
2o2bo4bo$bo3b2obob3o4bob4o2bo6bobob2obob2o2bo3bo4b5o4b2obo4bo4bo$o3bo
4b5o2bobobo2bo5bo2bob2obo3bo2bo7bo3bobo5bo3bo9bo$b3o3bobob3o4bo2bob2o
2bo3bobo8b2o7bo2b2o5bo13bo$o4bob3obobo4bo3bobo4b5obob2o13bo2bob2o7bo4b
2o3bo$2o4b2obob2obo6bobobo4bobo2b2ob2o2b2ob2o4b2obo9bobobobo7b2o$4bo3b
o9b3o12bo5b4obo2bobo2bobob2obob2o6b2o2b2o2bobo$8bo7bo2bo5bobo2b2o3bo3b
3o5bo6bo10b3o2bo3bobob2o$3bobo2bobo2bo2bo5bo2b2obo2bo4bobo2bobobo5bo3b
o4bo3bo3b3o4bob3o$b2obo3bo5bo2bo8b4o4b2obo6bo6bo4b2o3bo3b3o6b3o$3bo2bo
5bo2bo6bob2o2bo4bo4b2ob2ob3o2b2o3bo3bobo2b2o2b2o4bo3bobo$3bo2bo7b2o3b
2o7bobo10bobo2bobo5bo2bo5bo2bo5b3o$b2o2bobobo2bo4b2o3bob2o2b4o2bob2o2b
3o4bo2bob4o2bobo2bo2bo3bo5bo$2b3o2bob2o5bo2bobobo11bo2b2o4bo2bo2bo4b3o
3b5ob4o2b2o2bobo$3b2o3b3o3bo3b2o7bo4bobob2o4bobo7bo2bob2o3b2ob2o6b2obo
2bo$2b3o2b2o2bobo5bobo11b2ob2o6b2o11b2obo3bo4b2o$2bo3b2o8bo2bo15bobo3b
2obo4bob2obobobob2o3b3obob3ob2o2bo$2o4bo3b3o7bo3b2obo3bo3b2obobo3bob2o
bo7bobo4bob2o2b2o4bo2bo$o3bo2b3ob2ob2o3bob3obo3bo3b2ob2o2bo4b2o4b2o2bo
4bob2obo5b4obo$o4b3o4bo2bo2bo2b2o2b3o2b4ob2o2bo2bo3bo3b3ob2o4b2o5b3o6b
4o$5bobo2bob3o2bo2b3o2bob2o6bo2bo2b2ob2o3b2o3bo7bo3bo3b5o$bo5bo11bobo
2bo3b3o2bo2bobo2bo2b7o2bob2o4bo2b3obo4bo2bo$3bo4bobo8b2obo8bo3bo4bo4bo
2bobobo2bo3bobo10bo3bobo$o3b2o2bo2b5o2bobo8b3o2b2o3bobo2bo10bo6b3o2bo
7b3o$ob2o6bo7bob2o2bo3bobobo3b2o5bobo2bobo2bo8b2o2b3obo$4b5obobo5b2o3b
o3b3o4bo6bobo10bo2bo2bo4b3obo6bo2bo$bobo2bo4b4obo3b3o3b4obo3b2obobob2o
4bo3b2o3bo8bob2obo2bobob2o$2b3obo7bo5bo2b2ob2o3b2ob2obobo5bo4bo2bo2bob
o8bobo3b2o4bo!
User avatar
confocaloid
Posts: 6697
Joined: February 8th, 2022, 3:15 pm
Location: learn to protect yourself against stray gliders and sparks and self-destruct mechanisms

Re: Maximum lifespan on torus

Post by confocaloid »

Vort wrote: May 17th, 2024, 12:00 pm[...]
For comparison, here is result from random search on 80x80 torus, lifespan = 9419.
Looks like more live cells means more possibilities.
But I think engineered solutions will win eventually.
[...]
48668 ticks on the 80x80 torus, definitely suboptimal:

Code: Select all

#C period-184 glider gun followed by four quadri-Snarks
#C [[ THEME LifeHistory STOP 48667 ]]
x = 77, y = 75, rule = B3/S23:T80,80
40b2o2bo$39bob4o$39bo$37b2ob7o$35bo2bobo6bo$35b2o3bob2o2b2o$39b2ob2o7b
2o$52bo$50bo$50b5o$40bo13bo$39bobo6b4o$39bobo6bo2bo$40bo$55b2o$50b2obo
2bo$46bo3b2ob2o$45bobo$46bo3$39b2o$40bo$37b3o$35b3o$34bo$34b2o$46bo$
44b2o$46b2o$45bo3$71b2o$71bo$52b2o19bo$53bo18b2o$34bo18bobo8b2o4bo3b2o
$2bo30bobo18b2o7bo2bo3b4o2bo$2b3o15b2o10b2obo28b2o7bob2o$5bo13bobo5b2o
4bo3b2o2b2o6b3o18b2obobo$4b2o13bo7b2o5b2ob2o2b2o4bob3o18b2obobo$18b2o
14b2obobo6bobobo22bob2o$27b2o9b2o6bo2bo9bo13bo$11bo15b2o6b2o2bo7b2o9bo
bo10bobo$10bobo23b3o20bo11b2o$11bo3b2ob2obo14bo27b2o$15b2obob2o8b2o33b
o$30b2o28b2o3bob2o$5bo17bo36b2o2b2obo2bo$4bobo6bo2bo6bobo15bo25bob2o$
4bobo6b4o5bobo14b3o18b2o5bo$5bo13bo4bo13bo21bo5b2o$15b5o18b2o22bo$15bo
45b2o$17bo$4b2ob2o7b2o$2o3bob2o2b2o$o2bobo6bo11b2ob2o$2b2ob7o10bo2bob
2o$4bo17b2o$4bob4o28bo$5b2o2bo17bo2bo6bobo$27b4o6bobo$24bo13bo$24b5o$
28bo$26bo$26b2o7b2ob2o$31b2o2b2obo3b2o$31bo6bobo2bo$32b7ob2o$39bo$34b
4obo$34bo2b2o!
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
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.
User avatar
eRroR_6o6
Posts: 385
Joined: August 15th, 2023, 1:24 am
Location: somewhere over the rainbow

Re: Maximum lifespan on torus

Post by eRroR_6o6 »

confocaloid wrote: May 17th, 2024, 3:23 pm 48668 ticks on the 80x80 torus, definitely suboptimal:
very suboptimal

523,236 (at least I think so because it's hard to remember 6-digit numbers) ticks using 2 x11 pulse dividers, a block, and a Simkin glider gun (which could probably be replaceable with the p184 but I'm too lazy to do that)

Code: Select all

x = 80, y = 80, rule = B3/S23:T80,80
15b2o$2o12bo2bo$bo13b2o$bobo24b2o$2b2o24bo3b2o$8bo12bo8bo2bo$7bobo10bo
bo6b3o2b2o35b2o$8bo11bobo9b2o2bo34b2o$2b2o17bo7b3o2bobo$bobo25bo2b2obo
$bo28b2o3bobo$2o20bo10b2ob2o$21b2o11bo$21bobo9bo2b2o$8b2o24b2obo$8bo4b
2o$9bo3b2o$10bo$8bob5o29b2o$7bobo4bo8bo20b2o$7bobo2bo9bobo$8bo3b2o8bob
o$23bo23b2o$18b2o27b2o$17bobo$17bo26b2o$16b2o26b2o$10b2ob2o$7b2o2bobo$
6bo2b2o3bo$6bobo2b2obo$4b2obobobobo$4bo2bobo$6bobobo$5b2obobo$3bo2bob
2o$3b2o40b3o$45bo$44b3o14b2o$61bobo$20b2o41bo$19bo2bo40b2o$6b2o12b2o
33b2o$5bo2bo46b2o$6b2o$23b2o27b2o$23bo28b2o$bo22b3o$obo23bo$obo52b2o$b
o13b2ob2o35b2o$15b2obo2bo$18bob2o$18bo$17b2o$6bo7bobo2b2o$5bobo6b2o2bo
2bo$6bo12b2o4$3b2o3b2o$4bo3bo$b3o5b3o$bo9bo!
this is also definitely suboptimal

Code: Select all

x = 19, y = 37, rule = B3/S23
13b3o$12b4o$11b2obobo$13bobo$15bo12$10b2o$bobo7bobo$o7b2o3b2o$o3bo2b3o
3bo$o6b4obo$o2bo7bo$3o12bobo$18bo$14bo3bo$14bo3bo$18bo$9bo5bo2bo$8b3o
5b3o2$10bo$2bobo4b2o$5bo2b3o$5bo2b3o$2bo2bo2b2obo$3b3o3b3o$10bo!
User avatar
tommyaweosme
Posts: 1581
Joined: January 15th, 2024, 9:37 am

Re: Maximum lifespan on torus

Post by tommyaweosme »

get a methuselah lasting a long amount of time, get a big enough torus (with eaters where gliders and xwss come out) and watch the lifespan

or just do a rake with a puffer making eaters for it

edit: or better yet, make a machine that goes through every possible pattern in a 30x30 box and emulates it, and then self destructs, all in a torus! 2^900 generations at the very minimum
here's the gosper glider gun

Code: Select all

#R life
24bo$22bobo$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o$2o8bo3bob2o4b
obo$10bo5bo7bo$11bo3bo$12b2o!
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

tommyaweosme wrote: May 17th, 2024, 7:48 pm edit: or better yet, make a machine that goes through every possible pattern in a 30x30 box and emulates it, and then self destructs, all in a torus! 2^900 generations at the very minimum
Game of Life is Turing-complete, so it is possible to make counter and emulator on top of it, right.
(actually, strictly speaking, life on torus is not Turing-complete, but, practically, it is)
However such machine will be huge.
By dropping emulation idea and using just counter, space can be utilized more effectively.
But as confocaloid and eRroR_6o6 showed, counters can be created directly without Turing machine, which is even more space efficient.
confocaloid wrote: May 17th, 2024, 3:23 pm 48668 ticks on the 80x80 torus, definitely suboptimal:
eRroR_6o6 wrote: May 17th, 2024, 5:58 pm523,236 (at least I think so because it's hard to remember 6-digit numbers) ticks using 2 x11 pulse dividers, a block, and a Simkin glider gun (which could probably be replaceable with the p184 but I'm too lazy to do that)
So these are essentially
4 x base 4 digits counter with increment every 184 generation (184 * 4 * 4 * 4 * 4 = 47104)
and
2 x base 11 digits + 1 extra base 36 "digit" counter with increment every 120 generation (120 * 36 * 11 * 11 = 522720)
Thanks!
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

Here is my attempt at improving idea with counter further.
Lifespan is 1604778 (3312 * 4 * 11 * 11 + explosion).

Code: Select all

x = 80, y = 77, rule = B3/S23:T80,80
32b4o$23b2o6b2o2bo14b2o$23b2o5b2o2bo15b2o$31bo2bo$32b2o2$32b2o$31bo2bo
$13bo16b2o2bo15b2o$12bo18b2o2bo14b2o$9b2o4b3o14b4o$7b2o2bo6bo$8b2o4b2o
bo$15bobo$3b2o11bo21b2o$3b2o10b2o21b2o$15b2o$44b3o$4bo12bo20b2o3bo$3bo
14bo18bobo3bo3bo$2bo4bo6bo4bo16b2o5bo2bobo$2b3o3bo4bo3b3o25bobo2bo$2o
4b3o4b3o4b2o24bo3bo$bobo14bobo19bo9bo$bob6o4b6obo18bobo5b3o$2bo5bo4bo
5bo20bo$3b3o10b3o$5bo10bo5$60b2o$60bo$58bobo$58b2o$54bo$53bobo8b2o3bo$
53bobo9bo2bobo$21bo9bo22bo8bo4bobo$21b3o5b3o31b5obo$24bo3bo38bo$23b2o
3b2o33b2o3bo$63b2o4bo$40bob2o24b2o$40b2o2bo$12b2o12bo16bo$11bo2bo2b2o
6bobo12b2ob2o31b2o$12b2o2bobo7bo13bobo3b2o28bo$14b2o26bob2o2bo25bobo$
14bo26bobo2b3o7bo17b2o$11b2obo26bo2b2o9bobo11bo$11bo2bob2o24b2o2b3o6bo
bo10bobo$13b2ob2o13bo12bo2bo8bo12bo$30bobo11b2o3bo24b2o$6bo23bobo15b2o
24bobo$6b3o22bo29b2o13bo$9bo50bo2bo12b2o$8b2o51b2o$o24b2o52bo$o23bo2bo
51bo$11b2o12b2o$2b2o6bo2bo$2b2o7b2o63b2o$76b2o3$28b2o$23b2obo2bo$22bob
ob2o$22bobobo$23bobo2bo$19bobobobob2o$18bob2o2bobo$18bo3b2o2bo$19bobo
2b2o$18b2ob2o!
Version with more compact gun, lifespan: 19237820 (4416 * 36 * 11 * 11):

Code: Select all

x = 76, y = 79, rule = B3/S23:T80,80
18b2o$18b2o42bo9bo$62b3o5b3o$21b2o42bo3bo$21b2o41b2o3b2o2$24b2o$24b2o$
53b2o12bo$27b2o23bo2bo2b2o6bobo$27b2o24b2o2bobo7bo$55b2o$30b2o23bo$30b
2o20b2obo$52bo2bob2o$33b2o19b2ob2o13bo$14bo9bo8b2o36bobo$14b3o5b3o22bo
23bobo$17bo3bo14b2o9b3o22bo$16b2o3b2o13b2o12bo$49b2o$39b2o25b2o$39b2o
24bo2bo$19bo12b2o18b2o12b2o$18bobo6b2o2bo2bo7b2o7bo2bo$19bo7bobo2b2o8b
2o8b2o$30b2o$31bo$31bob2o$28b2obo2bo34b2o$14bo13b2ob2o31b2obo2bo$13bob
o47bobob2o$13bobo23bo23bobobo$14bo22b3o24bobo2bo$36bo23bobobobob2o$36b
2o21bob2o2bobo$19b2o38bo3b2o2bo$18bo2bo38bobo2b2o$19b2o12b2o24b2ob2o$
32bo2bo$33b2o$57b2o$47b2o7bo2bo$48bo7bo9b2o$16b2o29bo8bo2bo10b2o$16bo
2bob2o24b2o7b2o2bo9b2o$18b2obobo25bo5bo3b2o$19bobobo23b3o4b2o$17bo2bob
o23bo6b3o$17b2obobobobo19b2o6b2o$19bobo2b2obo27bo3b2o$19bo2b2o3bo28b2o
2bo13b2o$20b2o2bobo30b3o15bo$23b2ob2o30bo6bo6b3o$65bo6bo$50b3o12bo7b2o
$74bo$73bo$b2o60b2o8b2o$b2o22b2o36b2o$24bobo$25bo$2o$2o$22b2o11b3o8b2o
$3b2o17b2o9bo3bo8b2o$3b2o27bo4bo$32bo3bo$6b2o$6b2o24bo3bo$32bo4bo$9b2o
11b2o9bo3bo8b2o$9b2o11b2o11b3o8b2o2$12b2o$12b2o11bo$24bobo$15b2o8b2o$
15b2o!
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

As I can see, 80x80 world is clearly dominated by engineered patterns.
Best lifespan for 20x20 world was achieved by random search and I doubt other approaches can give much improvement.

But what about medium sized world - 40x40?
Can engineered patterns live longer here, or randomized methods will work better?

I tried both variants and here are the results:

Lifespan: 3494

Code: Select all

x = 39, y = 38, rule = B3/S23:T40,40
2o$2o$4b2o$4b2o31b2o$37b2o$19b2o6b2o$19b2o6b2o5b2o$34b2o2$16b2o13b2o$
16b2o13b2o2$19b2o7b2o$19b2o7b2o2$25b2o$25b2o9$2b2o5bo$bobo4b3o$bo5b2o
2bo$2o2$36b2o$10b2o24b2o$8b3o$9bo3$8b2o$8b2o!
Lifespan: 4332

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
2b2ob3o5b2o6bo2b2o2bo2bo2bobob2o$2o3bo2b2obo7bo2bo5bo2bo5bobo$obobob2o
12bo4bob2o7b2obo$4bobobo2bo4bobobob3ob2o4bobob2o$ob4o3bo2bobo7bo3bo2bo
b3o$obo6bo9b2o6bo2bo3bo$5bobo2b2o6b3o3bob2o3b3o2b3o$2o5bo2bob4o4bo2bo
10b2o3bo$b5ob2o4b2o2bo3b4obob3o2b4o2bo$o2bo5b2o3bo3bo2b2o2bo3bo4b2obob
o$obob3o3b3o2bo7bo2bo2bo4b3o$o4b2ob2o5bo2b5o5b2ob2o3bo$bobobo3b2obobo
2bo7b2obob3o5bo$b4o5b2o2b2o4b2o3b2o3bo2bobo$ob3obo3b2o3bo2b2obobo2bobo
4b2obo2bo$2bobo2bo3bo2b2o13b3ob2o$bob2o4bobo3b2o3bobo3bo3b3o2bobobo$2b
obob2obobobob2o4b2o6b3o3bo$2b2o3bo2b4o5bo3b3ob2obo3bo$8b2obobo4bo2bobo
4bo3bo3bo2bo$3bobo2bo6b5o2b3o6bob2o$o3bob3o4bo4bobo2b2o4bo6bob2o$o3bo
2bo4b2o3bobo3bo4b2obo2bob2o$4obo7bo2bob2o9b2o2bobobo$bo4bobo7bo3b2o2bo
3bo4bo3b2o$2bo5b2obo4bo5bo6bobo6bo$2b2o3bobo6bo3b2o5bobo3bo3bo$7b2o2bo
2bo2bob2o5b2o2bobo4b2o$2o5bobobo3bobobo10bobo2b5o$3o2bo7b2o2b2o3b4obo
4bo3b2o$o5b2ob4o2bobo2bo7bo5bobobo$o3bo6bobobo2b2o3bo4bobo4b3obo$2o5bo
2bo2bo6b4ob3ob2o7b2o$6bo6bob2obobobo6b2obo6bo$ob2o2bo5bobo2bobo2bo5b2o
b2o$o5bo2b2ob2o5bobo2bo2b2obo2b5obo$4b4o3bo7bo4bo2b3o5bo$4b3o2b2o3bobo
6bo4bobobo3b2obo$3b2obobo2b3o5bobo2b3o4bo6bo$7bobo2bo8bo5b2o3bob3obo!
User avatar
dvgrn
Moderator
Posts: 12023
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Maximum lifespan on torus

Post by dvgrn »

Vort wrote: May 20th, 2024, 5:20 am But what about medium sized world - 40x40?
Can engineered patterns live longer here, or randomized methods will work better?

I tried both variants and here are the results:

[Engineered] Lifespan: 3494 ...

[Random Soup] Lifespan: 4332 ...
Seems like there's probably some glider-eating trickery from the Engineered Diehards thread that can eat a lot more gliders before starting the destruction. Ships instead of blocks will allow a 240-tick improvement just for a start -- 3734 ticks:

Code: Select all

x = 39, y = 38, rule = B3/S23:T40,40
2o$2o$4b2o$4b2o31b2o$37b2o$19b2o6b2o$19b2o6b2o5b2o$33bobo$33b2o$16b2o
$16b2o12b2o$29bobo$19b2o8b2o$19b2o$26b2o$25bobo$25b2o9$2b2o5bo$bobo4b
3o$bo5b2o2bo$2o2$36b2o$10b2o24b2o$8b3o$9bo3$8b2o$8b2o!
Apparently tubs are even more packable -- 4214 ticks, closing in on the current random-soup record:

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
2bobo$3bo$o$bo3b2o32bo$o4b2o$37bo$20b2o6b2o6bobo$20b2o6b2o7bo$34bo$33b
obo$17b2o15bo$17b2o12bo$30bobo$20b2o9bo$20b2o$27b2o$26bobo$26b2o9$3b2o
5bo$2bobo4b3o$2bo5b2o2bo$b2o2$37b2o$11b2o24b2o$9b3o$10bo3$9b2o$9b2o$3b
o!
Then maybe a mixture of the engineered and randomized methods might work well, if nothing engineered can be found to pack into the remaining unused space: write a script to scatter some junk in the empty areas of the engineered pattern and look for the one that stays chaotic the longest.
User avatar
rowett
Moderator
Posts: 4587
Joined: January 31st, 2013, 2:34 am
Location: UK
Contact:

Re: Maximum lifespan on torus

Post by rowett »

Edit: Random pattern lifespan 7938 ticks.

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
6bo5b3o11b4o2bo$bo5b2o3bo3bo2bob2obo2bobo2bo6bo$bo5b2obobo2b2o6b2o6bo
2bo$8bobo5bo3bo2b3obo6bob2o$5bo13bo3bo6bo2bo$10bo2bob3o2bobobob3o2bo4b
2o$4bo2bo2bo5bo3bobobobo3bob2o2bo$o2bo5b2o2bo11bo10bobo$o6bo3b2o4bo14b
o2b2o$2b2ob4o2bo15bo3bobo4bo$2bo5bo3bob2obob2o2bo5bo2bo2bobo$obobo4b2o
2bo8bo3bo2bo3b2o$b2obobo3bo2bo4bo11bo2b3o2bo$2o11bo4bo6b3obobo3bob3o$
2bo11bo2bobo5bobo6b2o2b2o$5bo3bo4bo5bobobo14bo$bo2bob2o2bobobo2b4o5bo
3bobo3b3o$2obobo6bobo12bobo4bobob2o$4bo5bo6bobo12b2o5bo$bo24b2ob4obo$
2bo3bob2o5bo2b2obo5bo3b2o3bo2bo$o10bo10bobob2obo3b2o3bo$3b2obo2b2o5bo
14bo2bo2bo$3b2o4bo8b3o5bo10bo$2bo8bo12bo4bo$o4bobo2bo2b2o2bo3bo5bo5bo
$o7bo6bo2b2obo4bob3o3bo2bo$b2o6b3o2bo5b2obo2bo10bo$2bobo2b2o6bo3bo9bo
2b2o3bo$3b2o5b3o3bo2bo3bobo5bobo$o5bo3bo18bob2o3bo2bo$6bobobo6bo$2bob
o4bo15bobo3bo4bo2bo$o5b3o8bobo7bobobo2bobobo$2bo7bo2bo10bo6b3o$o2b4o8b
3o7b2obobo2bo5bo$bobo2bo5bo3bo4bo6bo3bo3b2o$3bo6bo2bo7bo6b2o3b6o$10bo
3bo10bo2b2o$5b2o2bo2bo12bo2bobo3bobo!
User avatar
confocaloid
Posts: 6697
Joined: February 8th, 2022, 3:15 pm
Location: learn to protect yourself against stray gliders and sparks and self-destruct mechanisms

Re: Maximum lifespan on torus

Post by confocaloid »

Engineered, lifespan 4539, likely can be improved by packing p1/p2 objects into the remaining empty space and rewinding via Logic Life Search/octohash:

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
9bo10bobo$9bo11bo3b2o$25b2o5$7b2o5b2o$7b2o5b2o2$11b2o$11b2o$16b2o$4b2o
9bo2bo$4b2o8b2o$15b2o17b2o$16bo17b2o2$31b2o5b2o$31b2o5b2o5$23bo10bo$
22bobo9bo$2b2o19bo10bo$2b2o22bo10bo$25bobo9bo$26bo10bo$o$o$o$3bo$3bo$
3bo$6bo$6bo11b2o$6bo12bo$9bo9bobo!
vilc
Posts: 311
Joined: March 20th, 2024, 4:36 pm

Re: Maximum lifespan on torus

Post by vilc »

Engineered methuselah in a 40x40 torus with lifespan 10242 (using a p1344 gun). There is a lot of space that the glider stream cannot reach, significant improvements might come from a gun with a better shape.

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
4$32bo$28b4obo$28bob2ob3o$26bo4bo4bo$26bo3bob3obo$30bobo$26bob3obo3bo$
26bo4bo4bo$27b3ob2obo$29bob4o$30bo$4b3o3$12b2o$2b2o8b2o23bo$3bo32bobo$
2bo34bo$2b2o30bo$4bo28bobo$2b3o29bo$bo16b2o17bo$b2o15b2o16bobo$37bo$
29b2o$30bo$9b2o9bo6b3o$8bobo9bo6bo$5bo4bo9bo7b2o$5b2o22bo$28bo$18b2o8b
2o$18b2o!
40x40 random soup (25%) with a lifespan of 6658 (low density empirically gives better results) :

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
bo2bobo4bobobo5bo3bo2bo8b3o$3b2obo2bo4bo2bo3bob3o3b2o4bo$4bo4bo13bo3bo
4bo$2obo5bobo5bobo5bobobo4bo2bobo$b2o4bo4b2o3bo9bo7b2o$2bo2bo6bo3bo2b
2o3b2obo2b2o$8bo2bobo5bobo4bob2o2b2obo2bo$bo4bo10b2obo6b4o6bobo$7b3o8b
o5bobo6bo$2bob2o3b2o4bo7bo10b2o$12b2o3b3o7b2o2bo6bo$7bo3bo2bo2bo3bobob
ob2o4b2o3bo$16bo2bo6bo4b2o2bobobo$3bobo2bo3bo4bo2b2o5bobob2o$o4bo5b2ob
o3bo2b2o3bo3bo4bo$bobo5b2obo6bo13bo$11bo7b2o$bo9bo3bo2b4o3bo9bo$11b2o
2bob2o2bobo8b2o2b4o$o6bo2b2obo4bo3b2o3bob2o$o4b2ob2o4bo2bo2bobo5bo3bob
o$bobo2bo3bo6b2o3bob2o4b2o7bo$2bobo5bobobo8bo11bobobo$2bobo5bo3bo4b2o
6b2o2bo$2o3bo13bobo2b2o2bo3bo3bo$bobo6bo4bo10bobo2b2obo3bo$3bo9bobobo
8b3obo3bo3bo$2bob4o7b2o8bo2bo$4obo2b2o4b2o6bo3bob2o8bo$3bo3bobo6bo3bo
6b3o$o11bo5bo6bo4bo2bo$3bobo2bobo10b2o10bo4bo$3b2o12bo3bo3bo$bo2bo9bo
2bo2b3o12bo2b2o$3bo8bo10b2obo3b2o2bob2o$4bo2bo5bo6bobo6bo2bo2bobobo$5b
o2bobo9bo3bob2obo5bo2bo$9bo2bo9bobobobo5bo$4bobo3bo5bo4bobobo2b2o3bo$
11bo2bob2o2bo2bo4bo4b2obo!
Edit :
Non-square tori allow for engineered methuselahs with high lifespan (especially if the width and height are coprimes) because diagonal spaceships become high-period oscillators. Example with a glider and a block achieving a lifespan of 4417 in a 40x39 torus :

Code: Select all

x = 23, y = 17, rule = B3/S23:T40,39
bo$2bo$3o13$21b2o$21b2o!
In general, the "period of the glider" in a MxN torus is 4 * lcm(M, N).
Last edited by vilc on May 24th, 2024, 1:01 pm, edited 1 time in total.
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

dvgrn wrote: May 20th, 2024, 7:19 amwrite a script to scatter some junk in the empty areas of the engineered pattern and look for the one that stays chaotic the longest
This approach allowed to improve lifespan from 4214 to 8058

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
2bobo7b2o6b2o2b2o2b2o$3bo8b2o6b2o2b2o2b2o$o$bo3b2o32bo$o4b2o5b2o$12b2o
23bo$20b2o6b2o6bobo$20b2o6b2o7bo$8b2o24bo$8b2o23bobo$17b2o15bo$17b2o
12bo$30bobo$20b2o9bo$20b2o$27b2o$26bobo$26b2o7$28b2o2b2o2b2o$28b2o2b2o
2b2o$3b2o5bo$2bobo4b3o$2bo5b2o2bo15b2o2b2o2b2o$b2o25b2o2b2o2b2o3$2o9b
2o15b2o2b2o2b2o$2o7b3o16b2o2b2o2b2o$10bo2$20b2o6b2o2b2o$9b2o9b2o6b2o2b
2o$9b2o$3bo!
Here is the code which I used (C#):

Code: Select all

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace TorusLife
{
    class Pattern
    {
        public const int GridWidth = 40;
        public const int GridHeight = 40;
        int[,] cells;

        public Pattern()
        {
            cells = new int[GridWidth, GridHeight];
        }

        public Pattern(Pattern source)
        {
            cells = new int[GridWidth, GridHeight];
            for (int y = 0; y < GridHeight; y++)
                for (int x = 0; x < GridWidth; x++)
                    cells[x, y] = source.cells[x, y];
        }

        public void Generate(Pattern old)
        {
            for (int y = 0; y < GridHeight; y++)
            {
                int ym1 = y - 1;
                int yp1 = y + 1;
                if (ym1 < 0)
                    ym1 = GridHeight - 1;
                else if (ym1 >= GridHeight)
                    ym1 = 0;
                if (yp1 < 0)
                    yp1 = GridHeight - 1;
                else if (yp1 >= GridHeight)
                    yp1 = 0;
                for (int x = 0; x < GridWidth; x++)
                {
                    int xm1 = x - 1;
                    int xp1 = x + 1;
                    if (xm1 < 0)
                        xm1 = GridWidth - 1;
                    else if (xm1 >= GridWidth)
                        xm1 = 0;
                    if (xp1 < 0)
                        xp1 = GridWidth - 1;
                    else if (xp1 >= GridWidth)
                        xp1 = 0;
                    int neighbours = 
                        old.cells[xm1, ym1] +
                        old.cells[x, ym1] +
                        old.cells[xp1, ym1] +
                        old.cells[xm1, y] +
                        old.cells[xp1, y] +
                        old.cells[xm1, yp1] +
                        old.cells[x, yp1] +
                        old.cells[xp1, yp1];

                    if (old.cells[x, y] == 1)
                        cells[x, y] = (neighbours == 2 || neighbours == 3) ? 1 : 0;
                    else
                        cells[x, y] = neighbours == 3 ? 1 : 0;
                }
            }
        }

        public void PlaceBlocks(Random rnd, Pattern mask)
        {
            for (int y = 0; y < GridHeight - 1; y += 4)
                for (int x = 0; x < GridWidth - 1; x += 4)
                    if (rnd.Next(0, 100) < 85)
                    {
                        bool intersects = false;
                        for (int i = 0; i < 6; i++)
                            for (int j = 0; j < 6; j++)
                            {
                                int cx = x + i - 2;
                                int cy = y + j - 2;
                                WrapCoordinates(ref cx, ref cy);
                                if (mask.cells[cx, cy] == 1)
                                    intersects = true;
                            }
                        if (intersects)
                            continue;
                        cells[x, y] = 1;
                        cells[x + 1, y] = 1;
                        cells[x, y + 1] = 1;
                        cells[x + 1, y + 1] = 1;
                    }
        }

        public void Measure(out int lifespan, out int period)
        {
            var patterns = new List<Pattern>();
            patterns.Add(this);

            for (int i = 0; ; i++)
            {
                Pattern newPattern = new Pattern();
                newPattern.Generate(patterns.Last());
                int start = patterns.Count - 2;
                if (start < 0)
                    start = 0;
                for (int j = start; j < patterns.Count; j++)
                {
                    if (newPattern.Equal(patterns[j]))
                    {
                        period = patterns.Count - j;
                        lifespan = i - period + 1;
                        return;
                    }
                }
                if (i > 12000) // hack
                {
                    period = 0;
                    lifespan = 0;
                    return;
                }
                patterns.Add(newPattern);
            }
        }

        public Pattern GetMask(int ticks)
        {
            Pattern mask = new Pattern();
            Pattern current = this;
            for (int i = 0; i < ticks; i++)
            {
                for (int y = 0; y < GridHeight; y++)
                    for (int x = 0; x < GridWidth; x++)
                        mask.cells[x, y] |= current.cells[x, y];

                Pattern next = new Pattern();
                next.Generate(current);
                current = next;
            }
            return mask;
        }

        public void WriteRLE(string fileName, string comment = null)
        {
            var sb = new StringBuilder();
            if (comment != null)
                sb.AppendLine($"#C {comment}");
            sb.AppendLine($"x = {GridWidth}, y = {GridHeight}, rule = B3/S23:T{GridWidth},{GridHeight}");
            for (int y = 0; y < GridHeight; y++)
            {
                for (int x = 0; x < GridWidth; x++)
                    sb.Append(cells[x, y] == 1 ? 'o' : 'b');
                sb.AppendLine(y == GridHeight - 1 ? "!" : "$");
            }
            File.WriteAllText(fileName, sb.ToString());
        }

        public void ReadRLE(string[] lines)
        {
            int x = 0;
            int y = 0;

            string scount = "";

            foreach (var line in lines)
            {
                if (line.StartsWith("#"))
                    continue;
                if (line.StartsWith("x"))
                {
                    if (line.Split(':')[1] != $"T{GridWidth},{GridHeight}")
                        throw new Exception();
                    continue;
                }

                for (int i = 0; i < line.Length; i++)
                {
                    char c = line[i];
                    if (c >= '0' && c <= '9')
                    {
                        scount += c;
                    }
                    else
                    {
                        if (c == '$')
                        {
                            x = 0;
                            int count = 1;
                            if (scount != "")
                                count = int.Parse(scount);
                            y += count;
                            scount = "";
                        }
                        else if (c == '!')
                            break;
                        else if (c == 'o' || c == 'b')
                        {
                            int count = 1;
                            if (scount != "")
                                count = int.Parse(scount);
                            for (int k = 0; k < count; k++)
                            {
                                cells[x, y] = c == 'o' ? 1 : 0;
                                x++;
                                WrapCoordinates(ref x, ref y);
                            }
                            scount = "";
                        }
                    }
                }
            }
        }

        public void ReadRLE(string fileName)
        {
            ReadRLE(File.ReadAllLines(fileName));
        }

        public bool Equal(Pattern pattern)
        {
            for (int y = 0; y < GridHeight; y++)
                for (int x = 0; x < GridWidth; x++)
                    if (cells[x, y] != pattern.cells[x, y])
                        return false;
            return true;
        }

        void WrapCoordinates(ref int x, ref int y)
        {
            if (x < 0)
                x = GridWidth - 1;
            else if (x >= GridWidth)
                x = 0;
            if (y < 0)
                y = GridHeight - 1;
            else if (y >= GridHeight)
                y = 0;
        }
    }

    class Program
    {
        Program()
        {
            Pattern source = new Pattern();
            source.ReadRLE(new string[] {
                "x = 40, y = 40, rule = B3/S23:T40,40",
                "2bobo$3bo$o$bo3b2o32bo$o4b2o$37bo$20b2o6b2o6bobo$20b2o6b2o7bo$34bo$33b",
                "obo$17b2o15bo$17b2o12bo$30bobo$20b2o9bo$20b2o$27b2o$26bobo$26b2o9$3b2o",
                "5bo$2bobo4b3o$2bo5b2o2bo$b2o3$11b2o$9b3o$10bo3$9b2o$9b2o$3bo!"
            });
            Pattern mask = source.GetMask(3331);

            int period;
            int lifespan;
            int totalMax = 0;
            int countMax = 0;
            int bestLifespan = 0;
            int bestLifespanLocal = 0;
            int failed = 0;

            Random rnd = new Random();

            for (int i = 0; ; i++)
            {
                Pattern pattern = new Pattern(source);
                pattern.PlaceBlocks(rnd, mask);
                pattern.Measure(out lifespan, out period);
                if (period == 0)
                    failed++;
                if (i % 20 == 0 && i != 0)
                {
                    totalMax += bestLifespanLocal;
                    countMax++;
                    int avgMax = totalMax / countMax;
                    Console.WriteLine($"Iteration: {i,6}, lifespan: {bestLifespan,4} | {bestLifespanLocal,4} | {avgMax,4}, failed: {failed}");
                    bestLifespanLocal = 0;
                    failed = 0;
                }
                if (lifespan > bestLifespan)
                {
                    bestLifespan = lifespan;
                    pattern.WriteRLE(
                        $"{Pattern.GridWidth}x{Pattern.GridHeight}_{lifespan}.rle",
                        $"lifespan: {lifespan}, period: {period}");
                }
                if (lifespan > bestLifespanLocal)
                    bestLifespanLocal = lifespan;
            }
        }

        static void Main(string[] args)
        {
            new Program();
        }
    }
}
User avatar
b-engine
Posts: 3762
Joined: October 26th, 2023, 4:11 am
Location: Somewhere on where Earth At
Contact:

Re: Maximum lifespan on torus

Post by b-engine »

I think we have this approach, like this example which has a lifespan of 25423:

Code: Select all

x = 100, y = 75, rule = B3/S23:T100,75
13bobo22bobo22bobo22bobo$14bo24bo24bo24bo$11bo24bo24bo24bo$10bobo22bo
bo22bobo22bobo$11bo24bo24bo24bo$8bo24bo24bo24bo$7bobo22bobo22bobo22bo
bo$8bo24bo24bo24bo$5bo24bo24bo24bo$4bobo22bobo22bobo22bobo$5bo24bo24b
o24bo$2bo24bo24bo24bo$bobo22bobo22bobo22bobo$2bo24bo24bo24bo$24bo24bo
24bo24bo$o22bobo22bobo22bobo22bo$24bo24bo24bo24bo$21bo24bo24bo24bo$20b
obo22bobo22bobo22bobo$21bo24bo24bo24bo$18bo24bo24bo24bo$17bobo22bobo22b
obo22bobo$18bo24bo6b2o16bo24bo$15bo24bo9b2o13bo24bo$14bobo22bobo22bob
o22bobo$15bo24bo24bo24bo$12bo24bo9b2o13bo24bo$11bobo22bobo8b2o12bobo22b
obo$12bo24bo24bo24bo$9bo24bo15b2o7bo24bo$8bobo22bobo14b2o6bobo22bobo$
9bo24bo24bo24bo$6bo24bo49bo$5bobo22bobo47bobo$6bo24bo49bo$3bo24bo49bo
$2bobo22bobo47bobo$3bo24bo49bo$o24bo49bo$bo22bobo47bobo22bo$o24bo49bo
$22bo49bo24bo$21bobo16bo30bobo22bobo$22bo10b2o4b3o30bo24bo$19bo14bo3b
2o2bo26bo24bo$18bobo10b3o34bobo22bobo$19bo11bo37bo24bo$16bo49bo24bo$15b
obo23b2o22bobo22bobo$16bo22b3o24bo24bo$13bo26bo22bo24bo$12bobo47bobo22b
obo$13bo49bo24bo$10bo28b2o19bo24bo$9bobo27b2o18bobo22bobo$10bo49bo24b
o$7bo24bo24bo24bo$6bobo22bobo22bobo22bobo$7bo24bo24bo24bo$4bo24bo24bo
24bo$3bobo22bobo22bobo22bobo$4bo24bo24bo24bo$bo24bo24bo24bo$obo22bobo
22bobo22bobo$bo24bo24bo24bo$23bo24bo24bo24bo$22bobo22bobo22bobo22bobo
$23bo24bo24bo24bo$20bo24bo24bo24bo$19bobo22bobo22bobo22bobo$20bo24bo24b
o24bo$17bo24bo24bo24bo$16bobo22bobo22bobo22bobo$17bo24bo24bo24bo$14bo
24bo24bo24bo!
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

b-engine wrote: May 21st, 2024, 3:32 amI think we have this approach...
The idea is to improve engineered solutions with randomization.
Better randomizer may mean better results with the same base pattern.
For example, this solution (lifespan 9437) differs from previous solution (8058) only because I applied different method for junk generation:

Code: Select all

x = 40, y = 40, rule = B3/S23:T40,40
2bobo26bo$3bo7b2o$o10b2o8b2o5b2o$bo3b2o9b2o3b2o5b2o9bo$o4b2o9b2o$37bo$
13bo6b2o6b2o6bobo$12bobo5b2o6b2o7bo$6b2o5bo20bo$6b2o25bobo$17b2o15bo$
17b2o12bo$30bobo$20b2o9bo$20b2o$27b2o$26bobo$26b2o5$28b2o6b2o$28b2o6b
2o2$31b2o$3b2o5bo20b2o4b2o$2bobo4b3o14bo10b2o$2bo5b2o2bo12bobo$b2o23bo
6b2o$33b2o2$2b2o7b2o11b2o3bo8b2o$2b2o5b3o12b2o2bobo7b2o$10bo18bo2$16b
2o9bo7bo$9b2o5b2o8bobo5bobo$9b2o11b2o3bo3bo3bo$3bo18b2o6bobo!
New code:

Code: Select all

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace TorusLife
{
    class Pattern
    {
        public const int GridWidth = 40;
        public const int GridHeight = 40;
        int[,] cells;

        public Pattern()
        {
            cells = new int[GridWidth, GridHeight];
        }

        public Pattern(Pattern source)
        {
            cells = new int[GridWidth, GridHeight];
            for (int y = 0; y < GridHeight; y++)
                for (int x = 0; x < GridWidth; x++)
                    cells[x, y] = source.cells[x, y];
        }

        public Pattern Generate()
        {
            var result = new Pattern();
            for (int y = 0; y < GridHeight; y++)
            {
                int ym1 = y - 1;
                int yp1 = y + 1;
                if (ym1 < 0)
                    ym1 = GridHeight - 1;
                else if (ym1 >= GridHeight)
                    ym1 = 0;
                if (yp1 < 0)
                    yp1 = GridHeight - 1;
                else if (yp1 >= GridHeight)
                    yp1 = 0;
                for (int x = 0; x < GridWidth; x++)
                {
                    int xm1 = x - 1;
                    int xp1 = x + 1;
                    if (xm1 < 0)
                        xm1 = GridWidth - 1;
                    else if (xm1 >= GridWidth)
                        xm1 = 0;
                    if (xp1 < 0)
                        xp1 = GridWidth - 1;
                    else if (xp1 >= GridWidth)
                        xp1 = 0;
                    int neighbours =
                        cells[xm1, ym1] +
                        cells[x, ym1] +
                        cells[xp1, ym1] +
                        cells[xm1, y] +
                        cells[xp1, y] +
                        cells[xm1, yp1] +
                        cells[x, yp1] +
                        cells[xp1, yp1];

                    if (cells[x, y] == 1)
                        result.cells[x, y] = (neighbours == 2 || neighbours == 3) ? 1 : 0;
                    else
                        result.cells[x, y] = neighbours == 3 ? 1 : 0;
                }
            }
            return result;
        }

        public void PlaceJunk(Random rnd, Pattern mask)
        {
            int[][,] stamps = new int[2][,]
            {
                new int[6, 6] {
                    { 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 1, 1, 0, 0 },
                    { 0, 0, 1, 1, 0, 0 },
                    { 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 0, 0, 0, 0 }
                },
                new int[7, 7] {
                    { 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 0, 1, 0, 0, 0 },
                    { 0, 0, 1, 0, 1, 0, 0 },
                    { 0, 0, 0, 1, 0, 0, 0 },
                    { 0, 0, 0, 0, 0, 0, 0 },
                    { 0, 0, 0, 0, 0, 0, 0 },
                }
            };

            int[][,] stampMasks = new int[2][,]
            {
                new int[6, 6] {
                    { 0, 1, 1, 1, 1, 0 },
                    { 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1 },
                    { 0, 1, 1, 1, 1, 0 }
                },
                new int[7, 7] {
                    { 0, 0, 1, 1, 1, 0, 0 },
                    { 0, 1, 1, 1, 1, 1, 0 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 },
                    { 0, 1, 1, 1, 1, 1, 0 },
                    { 0, 0, 1, 1, 1, 0, 0 },
                }
            };

            for (int i = 0; i < 2000; i++)
            {
                int stampIndex = rnd.Next(stamps.Length);
                int[,] stamp = stamps[stampIndex];
                int[,] stampMask = stampMasks[stampIndex];
                int stampWidth = stamp.GetLength(0);
                int stampHeight = stamp.GetLength(1);
                int offsetX = rnd.Next(GridWidth);
                int offsetY = rnd.Next(GridHeight);
                bool collided = false;
                for (int y = 0; y < stampHeight; y++)
                    for (int x = 0; x < stampWidth; x++)
                    {
                        int sX = x + offsetX;
                        int sY = y + offsetY;
                        WrapCoordinates(ref sX, ref sY);

                        if (stampMask[x, y] == 1 &&
                            (mask.cells[sX, sY] == 1 ||
                            cells[sX, sY] == 1))
                        {
                            collided = true;
                            break;
                        }
                        if (collided)
                            break;
                    }
                if (!collided)
                {
                    for (int y = 0; y < stampHeight; y++)
                        for (int x = 0; x < stampWidth; x++)
                        {
                            int sX = x + offsetX;
                            int sY = y + offsetY;
                            WrapCoordinates(ref sX, ref sY);
                            cells[sX, sY] |= stamp[x, y];
                        }
                }
            }
        }

        public void Measure(out int lifespan, out int period)
        {
            var patterns = new List<Pattern>();
            patterns.Add(this);

            for (int i = 0; ; i++)
            {
                Pattern newPattern = patterns.Last().Generate();
                int start = patterns.Count - 2;
                if (start < 0)
                    start = 0;
                for (int j = start; j < patterns.Count; j++)
                {
                    if (newPattern.Equal(patterns[j]))
                    {
                        period = patterns.Count - j;
                        lifespan = i - period + 1;
                        return;
                    }
                }
                if (i > 12000) // hack
                {
                    period = 0;
                    lifespan = 0;
                    return;
                }
                patterns.Add(newPattern);
            }
        }

        public Pattern GetMask(int ticks)
        {
            Pattern mask = new Pattern();
            Pattern current = this;
            for (int i = 0; i < ticks; i++)
            {
                for (int y = 0; y < GridHeight; y++)
                    for (int x = 0; x < GridWidth; x++)
                        mask.cells[x, y] |= current.cells[x, y];
                current = current.Generate();
            }
            return mask;
        }

        public void Merge(Pattern pattern)
        {
            for (int y = 0; y < GridHeight; y++)
                for (int x = 0; x < GridWidth; x++)
                    cells[x, y] |= pattern.cells[x, y];
        }

        public void WriteRLE(string fileName, string comment = null)
        {
            var sb = new StringBuilder();
            if (comment != null)
                sb.AppendLine($"#C {comment}");
            sb.AppendLine($"x = {GridWidth}, y = {GridHeight}, rule = B3/S23:T{GridWidth},{GridHeight}");
            for (int y = 0; y < GridHeight; y++)
            {
                for (int x = 0; x < GridWidth; x++)
                    sb.Append(cells[x, y] == 1 ? 'o' : 'b');
                sb.AppendLine(y == GridHeight - 1 ? "!" : "$");
            }
            File.WriteAllText(fileName, sb.ToString());
        }

        public void ReadRLE(string[] lines)
        {
            int x = 0;
            int y = 0;

            string scount = "";

            foreach (var line in lines)
            {
                if (line.StartsWith("#"))
                    continue;
                if (line.StartsWith("x"))
                {
                    if (line.Split(':')[1] != $"T{GridWidth},{GridHeight}")
                        throw new Exception();
                    continue;
                }

                for (int i = 0; i < line.Length; i++)
                {
                    char c = line[i];
                    if (c >= '0' && c <= '9')
                    {
                        scount += c;
                    }
                    else
                    {
                        if (c == '$')
                        {
                            x = 0;
                            int count = 1;
                            if (scount != "")
                                count = int.Parse(scount);
                            y += count;
                            scount = "";
                        }
                        else if (c == '!')
                            break;
                        else if (c == 'o' || c == 'b')
                        {
                            int count = 1;
                            if (scount != "")
                                count = int.Parse(scount);
                            for (int k = 0; k < count; k++)
                            {
                                cells[x, y] = c == 'o' ? 1 : 0;
                                x++;
                                WrapCoordinates(ref x, ref y);
                            }
                            scount = "";
                        }
                    }
                }
            }
        }

        public void ReadRLE(string fileName)
        {
            ReadRLE(File.ReadAllLines(fileName));
        }

        public bool Equal(Pattern pattern)
        {
            for (int y = 0; y < GridHeight; y++)
                for (int x = 0; x < GridWidth; x++)
                    if (cells[x, y] != pattern.cells[x, y])
                        return false;
            return true;
        }

        void WrapCoordinates(ref int x, ref int y)
        {
            if (x < 0)
                x += GridWidth;
            else if (x >= GridWidth)
                x -= GridWidth;
            if (y < 0)
                y += GridHeight;
            else if (y >= GridHeight)
                y -= GridWidth;
        }
    }

    class Program
    {
        Program()
        {
            Pattern source = new Pattern();
            source.ReadRLE(new string[] {
                "x = 40, y = 40, rule = B3/S23:T40,40",
                "2bobo$3bo$o$bo3b2o32bo$o4b2o$37bo$20b2o6b2o6bobo$20b2o6b2o7bo$34bo$33b",
                "obo$17b2o15bo$17b2o12bo$30bobo$20b2o9bo$20b2o$27b2o$26bobo$26b2o9$3b2o",
                "5bo$2bobo4b3o$2bo5b2o2bo$b2o3$11b2o$9b3o$10bo3$9b2o$9b2o$3bo!"
            });
            int unstableTicks = 3203;
            Pattern mask = source.GetMask(unstableTicks);
            Pattern unstableSource = new Pattern(source);
            for (int i = 0; i < unstableTicks; i++)
                unstableSource = unstableSource.Generate();

            int period;
            int lifespan;
            int totalMax = 0;
            int countMax = 0;
            int bestLifespan = 0;
            int bestLifespanLocal = 0;
            int failed = 0;

            Random rnd = new Random();

            for (int i = 0; ; i++)
            {
                Pattern junk = new Pattern();
                junk.PlaceJunk(rnd, mask);
                Pattern pattern = new Pattern(unstableSource);
                pattern.Merge(junk);
                pattern.Measure(out lifespan, out period);
                lifespan += unstableTicks;

                if (period == 0)
                    failed++;
                if (i % 20 == 0 && i != 0)
                {
                    totalMax += bestLifespanLocal;
                    countMax++;
                    int avgMax = totalMax / countMax;
                    Console.WriteLine($"Iteration: {i,6}, lifespan: {bestLifespan,4} | {bestLifespanLocal,4} | {avgMax,4}, failed: {failed}");
                    bestLifespanLocal = 0;
                    failed = 0;
                }
                if (lifespan > bestLifespan)
                {
                    bestLifespan = lifespan;
                    pattern = new Pattern(source);
                    pattern.Merge(junk);
                    pattern.WriteRLE(
                        $"{Pattern.GridWidth}x{Pattern.GridHeight}_{lifespan}.rle",
                        $"lifespan: {lifespan}, period: {period}");
                }
                if (lifespan > bestLifespanLocal)
                    bestLifespanLocal = lifespan;
            }
        }

        static void Main(string[] args)
        {
            new Program();
        }
    }
}
vilc
Posts: 311
Joined: March 20th, 2024, 4:36 pm

Re: Maximum lifespan on torus

Post by vilc »

I decided to investigate exhaustively small square tori.
On a 1x1 torus, the maximum lifespan is (trivially) 1 :

Code: Select all

x = 1, y = 1, rule = B3/S23:T1,1
o!
On a 2x2 torus, the maximum lifespan is still 1 :

Code: Select all

x = 1, y = 1, rule = B3/S23:T2,2
o!
On a 3x3 torus, the maximum lifespan is 2 :

Code: Select all

x = 3, y = 1, rule = B3/S23:T3,3
3o!
On a 4x4 torus, the maximum lifespan is 9 :

Code: Select all

x = 3, y = 3, rule = B3/S23:T4,4
2o$2bo$3o!
On a 5x5 torus, the maximum lifespan is 51 :

Code: Select all

x = 5, y = 5, rule = B3/S23:T5,5
4o$obo$3bo$obo$2bo!
The search for the 6x6 torus is around 8% complete and should be finished tomorrow. A preliminary result (likely optimal) is this methusalah with lifespan 90 :

Code: Select all

x = 6, y = 6, rule = B3/S23:T6,6
o3b2o$bobo$2o2b2o$2obo$obo$o!
User avatar
b-engine
Posts: 3762
Joined: October 26th, 2023, 4:11 am
Location: Somewhere on where Earth At
Contact:

Re: Maximum lifespan on torus

Post by b-engine »

vilc wrote: May 25th, 2024, 10:58 am I decided to investigate exhaustively small square tori.
If we apply this to 1xN torus, we have different outcome:

L1, lifespan 1:

Code: Select all

x = 1, y = 1, rule = B3/S23:T1,1
o!
L2, lifespan 1:

Code: Select all

x = 2, y = 1, rule = B3/S23:T2,1
2o!
L3, lifespan 2:

Code: Select all

x = 1, y = 1, rule = B3/S23:T3,1
o!
L4, lifespan 2:

Code: Select all

x = 1, y = 1, rule = B3/S23:T4,1
o!
L5, lifespan 5:

Code: Select all

x = 1, y = 1, rule = B3/S23:T5,1
o!
L6, lifespan 5:

Code: Select all

x = 2, y = 1, rule = B3/S23:T2,1
o!
L7, lifespan 5:

Code: Select all

x = 3, y = 1, rule = B3/S23:T7,1
obo!
L8, lifespan 6:

Code: Select all

x = 4, y = 1, rule = B3/S23:T8,1
2obo!
User avatar
Vort
Posts: 248
Joined: May 14th, 2024, 6:35 am

Re: Maximum lifespan on torus

Post by Vort »

vilc wrote: May 25th, 2024, 10:58 am I decided to investigate exhaustively small square tori.
It was interesting for me to see how function of lifespan depending on world size looks like.
So you got first points for it, nice.
vilc wrote: May 25th, 2024, 10:58 amA preliminary result (likely optimal) is this methusalah with lifespan 90
I noticed max lifespan results do not end with oscillations.
Coincidence? Or this is how optimal result looks like?
User avatar
tommyaweosme
Posts: 1581
Joined: January 15th, 2024, 9:37 am

Re: Maximum lifespan on torus

Post by tommyaweosme »

a methuselah in a 1x8 bounded grid could only last at absolute most 256 generations in any rule. even hrot r8.
edit: this applies to 2 state rules only
Last edited by tommyaweosme on May 26th, 2024, 4:05 pm, edited 1 time in total.
here's the gosper glider gun

Code: Select all

#R life
24bo$22bobo$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o$2o8bo3bob2o4b
obo$10bo5bo7bo$11bo3bo$12b2o!
vilc
Posts: 311
Joined: March 20th, 2024, 4:36 pm

Re: Maximum lifespan on torus

Post by vilc »

Optimality of the 6x6 methuselah is confirmed.
The 7x7 case is currently out of my reach (it's probably feasible in a few days with better algorithms and a GPU implementation).

Randomized experiments gave a soup that lasts 216 generations on a 7x7 torus ...

Code: Select all

x = 7, y = 7, rule = B3/S23:T7,7
bobo$3o$ob3obo$3bob2o$bobo2bo$b3ob2o$4b3o!
... and another that lasts 327 generations on a 8x8 torus :

Code: Select all

x = 8, y = 8, rule = B3/S23:T8,8
ob3o2bo$bob2o$ob5o$3bobo$2bob4o$6bo$bo3b2o$ob3o2bo!
Let's consider nxn tori in general.
The maximum lifespan is almost constant at the smallest sizes (1x1, 2x2 and 3x3), it looks like it increases linearly at slightly larger sizes (compare 6x6, 7x7 and 8x8). We also know that it increases like exp(O(n^2)) when period-multiplying mecanisms become available, and that an upper bound on the maximum lifespan (2^(n^2)) increases in the latter way too.
How many stages of complexity are there between those extremes ? For example, can we distinguish polynomial or exponential stages caused by specific classes of reactions ?
Vort wrote: May 26th, 2024, 11:56 am I noticed max lifespan results do not end with oscillations.
Coincidence? Or this is how optimal result looks like?
The fact that most of them died intrigued me too. I don't think this is a general property of optimal results, but more probably a property of small tori. In fact, most soups die, especially the long-lasting ones. After computing some statistics, I came to the following heuristic (it seems to explain why dying soups are the most frequent, and why the discrepancy diminishes when the size gets larger) :

Soups have two kinds of stages. Either they look like space dust, with no structure, or they are almost stabilised into a small active region plus some (or no) stable objects. If there is an object, it will probably launch in turn some activity by colliding the active region because there is not much space, and again until the active region is small and alone. In this last case it is likely a spark and dies.

Note :
It works for 5x5 to 8x8 only. 1x1 and 2x2 don't have nonempty stable patterns, and in 3x3 stable patterns don't have predessors. 4x4 is an exception because it is an intermediate between extremely small tori and "just small" tori (this is also worth for the remarks above on lifespan increasement relative to size of torus).

Of course I would prefer an actual proof or a precise statistical argument. The former looks impossible, any idea for the latter ?

Here is my data (format is lifespan | dying soups count | surviving soups count):
3x3 torus (exhaustive) :

Code: Select all

0 1 126
1 301 0
2 84 0
4x4 torus (exhaustive) :

Code: Select all

0 1 1244
1 9627 3048
2 15104 2560
3 12480 2816
4 7168 1984
5 1856 1952
6 1728 1216
7 896 960
8 256 512
9 0 128
5x5 torus (exhaustive) :

Code: Select all

0 1 8405
1 1061706 428650
2 4708545 1007150
3 2557545 1299025
4 1365235 911700
5 1271310 876550
6 1482910 709950
7 1405000 602100
8 1216300 585700
9 1158650 544500
10 933400 497500
11 936500 420400
12 728300 302600
13 629200 228500
14 535300 198000
15 465300 189400
16 393300 167400
17 335200 155200
18 335600 132800
19 250100 119600
20 237500 111400
21 184600 155800
22 163500 91800
23 137300 75200
24 120800 55400
25 105600 56600
26 78200 42600
27 108800 33800
28 110200 21200
29 92200 15000
30 73000 10600
31 48600 5600
32 43000 2600
33 37000 2000
34 30600 200
35 21600 600
36 26800 200
37 20000 400
38 26400 400
39 11000 0
40 7600 0
41 4400 0
42 3800 0
43 3000 0
44 2400 0
45 2000 0
46 2400 0
47 5600 0
48 6200 0
49 2400 0
50 1600 0
51 400 0
And finally, statistics over 100,000,000 random soups on 6x6, 7x7 and 8x8 tori :
Attachments
small_tori_lifespan_statistics.zip
(4.25 KiB) Downloaded 56 times
User avatar
tommyaweosme
Posts: 1581
Joined: January 15th, 2024, 9:37 am

Re: Maximum lifespan on torus

Post by tommyaweosme »

5k generations. absolutely suboptimal, but fun to watch and gives off that time travel vibe.

Code: Select all

x = 36, y = 9, rule = B3/S23:T100,100+30
24bo$22bobo$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o$2o8bo3bob2o4b
obo$10bo5bo7bo$11bo3bo$12b2o!
here's the gosper glider gun

Code: Select all

#R life
24bo$22bobo$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o$2o8bo3bob2o4b
obo$10bo5bo7bo$11bo3bo$12b2o!
iddi01
Posts: 187
Joined: January 24th, 2024, 5:14 am
Location: B3-n/S1e2-a3-e4e

249 generations, 10x10 torus

Post by iddi01 »

Using my methuselah searcher, i got 249 generations on 10x10 torus:

Code: Select all

x = 10, y = 10, rule = B3/S23:T10,10
3bob3o$3bo3b2o$bobo2bob2o$bobo$bo3bo$o3b2obo$bo3b3o$o3bobo2bo$3bo5bo$
2o3bo2bo!
Also, anyone else thinks this thread belongs better in Patterns forum?
Wiki: User:iddi01

I'm making a poll. please contribute.

First gun i constructed:

Code: Select all

x = 69, y = 69, rule = B3-n/S1e2-a3-e4e
2$32b3o$32bobo$32bobo$32b3o27$63b4o$b4o58bo2bo$bo2bo23bo4b2o28b4o$b4o
21bobo$28bo21$35bo$34b3o6$33b3o$33bobo$33bobo$33b3o!
Post Reply