Reviving an old problem:
dvgrn wrote: ↑February 24th, 2017, 7:12 pm
Rhombic wrote:1) How does apgcode for yl work?
I can't explain all the details, but the apgsearch v1.1 code that generates the yl apgcode is fairly readable. The punchline is
q = deepperiod(difflist, maxperiod, 0)
prehash = str(moments[1]) + "#" + str(moments[2])
return "yl" + str(p) + "_" + str(q) + "_" + str(moments[0]) + "_" + hashlib.md5(prehash).hexdigest()
In other words, the apgcode is the concatenation of the
period-but-not-really, the deepperiod return value q*, moment #0, and a hashed version of moments #1 and #2.
There have been
previous requests for clarification on this point, I see.
Code: Select all
# Gets the period of an interleaving of degree-d polynomials:
def deepperiod(sequence, maxperiod, degree):
for p in xrange(1, maxperiod, 1):
good = True
for i in xrange(maxperiod):
diffs = [0] * (degree + 2)
for j in xrange(degree + 2):
diffs[j] = sequence[i + j*p]
# Produce successive differences:
for j in xrange(degree + 1):
for k in xrange(degree + 1):
diffs[k] = diffs[k] - diffs[k + 1]
if (diffs[0] != 0):
good = False
break
if (good):
return p
return -1
# Analyses a linear-growth pattern, returning a hash:
def linearlyse(maxperiod):
poplist = [0]*(3*maxperiod)
for i in xrange(3*maxperiod):
g.run(1)
poplist[i] = int(g.getpop())
p = deepperiod(poplist, maxperiod, 1)
if (p == -1):
return "unidentified"
difflist = [0]*(2*maxperiod)
for i in xrange(2*maxperiod):
difflist[i] = poplist[i + p] - poplist[i]
q = deepperiod(difflist, maxperiod, 0)
moments = [0, 0, 0]
for i in xrange(p):
moments[0] += (poplist[i + q] - poplist[i])
moments[1] += (poplist[i + q] - poplist[i]) ** 2
moments[2] += (poplist[i + q] - poplist[i]) ** 3
prehash = str(moments[1]) + "#" + str(moments[2])
# Linear-growth patterns with growth rate zero are clearly errors!
if (moments[0] == 0):
return "unidentified"
return "yl" + str(p) + "_" + str(q) + "_" + str(moments[0]) + "_" + hashlib.md5(prehash).hexdigest()
Maybe someone can clarify: moment #0 is often the population change per period, but not always -- not when q>1, possibly?
For
yl384_2_342_148fdc95f876989b992da6215c6840eb, for example, q=2, and the population goes up by 340 cells per 384 ticks, but moment #0 shows up as 342.
* q, the return value of the deepperiod() call, seems to be "1" most of the time, occasionally "2", and maybe some higher integer occasionally but
not that I've seen.
Looking closer, the population does not simply "goes up by 340 cells per 384 ticks". Each period a beacon is laid on the symmetric axis, whose population fluctuates by 2, and this matters when measuring the pop differences of this puffer before&after 384 ticks. If the beacon is in the ON phase then you get an increment of 172 cells, and if it is OFF then the increment becomes 170. These 2 types of pop differences sum to 342, and I think this is where 2 and 342 come from.
Similar explanations can be made for other cases. Take
this census as an OCA example. The underlying mechanism is a p13 gun shooting a p2 spaceship whose pop alternates between 5 and 7, but they appear in different conditions:
#1 is a stand-alone version, so every possible 26-tick interval gives only 1 type of pop diff, that is 5+7=12, hence yl26_1_12;
#2 has two of it connected back-to-back, so every possible 26-tick interval also gives only 1 type of pop diff, that is (5+7)*2=24, hence yl26_1_24;
#3 has two of it shooting face-to-face and making a period-doubled double-barrelled gun, so every possible 26-tick interval gives either of 2 types of pop diff, one is 5*2=10 and another 7*2=14, and 14+10=24, hence yl26_2_24.
For me, it appears so far that the scheme fails only in one linear growth, that is
this kaleidoscopic methuselah. The pattern becomes predicable at generation 264,694, after which the backfire glider pairs will be bounced by blocks (as in glider-block cycle) and annihilate with another pair, never catching up with the p589 ark, and therefore the pop cannot be decreasing.
(Bonus tip: the negative term in
another irrelevant case oddly makes some sense — when a p12 c/2 wickstretcher gets burnt, it gains 6 cells at the front but loses 12 cells at the back, so the only 1 type of pop diff is 6-12=(-6). But that means apgsearch didn't wait long enough before censusing the ash.)
EDIT:
a related challenge in sandbox