x = 17, y = 10, rule = B3/S23
b2ob2obo5b2o$11b4obo$2bob3o2bo2b3o$bo3b2o4b2o$o2bo2bob2o3b4o$bob2obo5b
o2b2o$2b2o4bobo2b3o$bo3b5ob2obobo$2bo5bob2o$4bob2o2bobobo!
x = 17, y = 10, rule = B3/S23
b2ob2obo5b2o$11b4obo$2bob3o2bo2b3o$bo3b2o4b2o$o2bo2bob2o3b4o$bob2obo5b
o2b2o$2b2o4bobo2b3o$bo3b5ob2obobo$2bo5bob2o$4bob2o2bobobo!
Saka wrote:https://catagolue.appspot.com/census/b3s238/C1/xs38
muzik wrote:xq4 isn't appearing here for some reason.
https://catagolue.appspot.com/census/r2b4t4s10t19/C1
EDIT: neither are any still lifes.
muzik wrote:Also, here's the period 68 oscillator with the lowest known period:
https://catagolue.appspot.com/census/b2 ... D2_+1/xp68
drc wrote:muzik wrote:Also, here's the period 68 oscillator with the lowest known period:
https://catagolue.appspot.com/census/b2 ... D2_+1/xp68
What the freaking hell? Why is that there? Spooky o.o
x = 16, y = 31, rule = B2e3aeij4-artyz5eikq6kn7c8/S23-akn4-ejkn5aekqy6-ak8
obob4o3b2ob2o$o3bo3bo2bo$b2obo3bo4bobo$3ob3o5b2o$2bob3obo$bo2bob5obob
2o$3o3bo2b2obobo$o3bo4bo2bo2bo$bob3ob5o2bo$bo3bob5ob3o$ob4o6bo2bo$2obo
3bo3b2ob2o$b3o2bo2bo2b2o$bob2ob2ob2ob4o$2bo3b2o2bo2bobo$3o2b4o3b3o$2bo
3b2o2bo2bobo$bob2ob2ob2ob4o$b3o2bo2bo2b2o$2obo3bo3b2ob2o$ob4o6bo2bo$bo
3bob5ob3o$bob3ob5o2bo$o3bo4bo2bo2bo$3o3bo2b2obobo$bo2bob5obob2o$2bob3o
bo$3ob3o5b2o$b2obo3bo4bobo$o3bo3bo2bo$obob4o3b2ob2o!
calcyman wrote:drc wrote:muzik wrote:Also, here's the period 68 oscillator with the lowest known period:
https://catagolue.appspot.com/census/b2 ... D2_+1/xp68
What the freaking hell? Why is that there? Spooky o.o
It seems to arise when a p68 is born between that constellation of blinkers. But I have no idea why the four temporary blinkers have been conflated into another p68:Code: Select allx = 16, y = 31, rule = B2e3aeij4-artyz5eikq6kn7c8/S23-akn4-ejkn5aekqy6-ak8
obob4o3b2ob2o$o3bo3bo2bo$b2obo3bo4bobo$3ob3o5b2o$2bob3obo$bo2bob5obob
2o$3o3bo2b2obobo$o3bo4bo2bo2bo$bob3ob5o2bo$bo3bob5ob3o$ob4o6bo2bo$2obo
3bo3b2ob2o$b3o2bo2bo2b2o$bob2ob2ob2ob4o$2bo3b2o2bo2bobo$3o2b4o3b3o$2bo
3b2o2bo2bobo$bob2ob2ob2ob4o$b3o2bo2bo2b2o$2obo3bo3b2ob2o$ob4o6bo2bo$bo
3bob5ob3o$bob3ob5o2bo$o3bo4bo2bo2bo$3o3bo2b2obobo$bo2bob5obob2o$2bob3o
bo$3ob3o5b2o$b2obo3bo4bobo$o3bo3bo2bo$obob4o3b2ob2o!
x = 17, y = 10, rule = B3/S23
b2ob2obo5b2o$11b4obo$2bob3o2bo2b3o$bo3b2o4b2o$o2bo2bob2o3b4o$bob2obo5b
o2b2o$2b2o4bobo2b3o$bo3b5ob2obobo$2bo5bob2o$4bob2o2bobobo!
Apple Bottom wrote:Catagolue also has some ambiguous rulestrings, e.g. b3s2a2c2e2i2k2n3 and b3s2-aceikn2aceikn3. (You can probably guess who submitted results to those.) ... b2cccccccccccccccccccs, that's fine. b37-ces239, sure, why not. They're not canonical, but there's no doubt as to which rule (i.e. CA) they represent. Rulestrings that do not unambiguously refer to one and only one rule, on the other hand, suck.
mniemiec wrote:How is it possible for a rule string to ambiguously refer to two different rules? The rules ones you mentioned above are all unambiguous. (I.e. s2a2c... enables all survival on 2, less 2a, then enables all survival on 2, less 2c, etc.)
I'm not sure how to even get apgmera to accept non-canonical rule strings without deliberately butchering the source code to do so. Every time I have entered a non-canonical rule string (inadvertently), it rejected it because it wasn't canonical. However, if this is allowed, it causes a bigger problem, because hauls for two identical rules are stored in different places, and it's not easy to even find the ones with non-canonical strings unless you specifically look for them by their non-canonical names.
Apple_Bottom wrote:Under your interpretation, e.g. "B2a2e/S3" is equivalent to "B2ae/S3". Under my interpretation, it is instead equivalent to "B2e/S3". And there is nothing in the notation the compels either interpretation.
Apple_Bottom wrote:I think apgsearch 1.x is more forgiving in this regard than the later C++ versions.
mniemiec wrote:Apple_Bottom wrote:Under your interpretation, e.g. "B2a2e/S3" is equivalent to "B2ae/S3". Under my interpretation, it is instead equivalent to "B2e/S3". And there is nothing in the notation the compels either interpretation.
No, I would also interpret it as "B2e/S3".
x = 3, y = 3, rule = B3c3e3k3a3i3n3y3q3j3r/S2c2e2k2a2i2n3c3e3k3a3i3n3y3q3j3r
obo$obo$3o!
dvgrn wrote:dvgrn wrote:In isotropic non-totalistic space there are 102 bits. [B0, B1c ... B7e, B8] and [S0, S1c ... S7e, S8] can be present in the rule, or not. Here's the full list:
B0 = B0 (i.e., there's still only one way for a cell to have zero neighbors)
B1 = B1c, B1e
B2 = B2c, B2e, B2k, B2a, B2i, B2n
B3 = B3c, B3e, B3k, B3a, B3i, B3n, B3y, B3q, B3j, B3r
B4 = B4c, B4e, B4k, B4a, B4i, B4n, B4y, B4q, B4j, B4r, B4t, B4w, B4z
B5 = B5c, B5e, B5k, B5a, B5i, B5n, B5y, B5q, B5j, B5r
B6 = B6c, B6e, B6k, B6a, B6i, B6n
B7 = B7c, B7e
B8 = B8
S0 = S0
S1 = S1c, S1e
S2 = S2c, S2e, S2k, S2a, S2i, S2n
S3 = S3c, S3e, S3k, S3a, S3i, S3n, S3y, S3q, S3j, S3r
S4 = S4c, S4e, S4k, S4a, S4i, S4n, S4y, S4q, S4j, S4r, S4t, S4w, S4z
S5 = S5c, S5e, S5k, S5a, S5i, S5n, S5y, S5q, S5j, S5r
S6 = S6c, S6e, S6k, S6a, S6i, S6n
S7 = S7c, S7e
S8 = S8
For example, good old B3/S23 could be thought of as this collection of isotropic bits:
B3c, B3e, B3k, B3a, B3i, B3n, B3y, B3q, B3j, B3r /
S2c, S2e, S2k, S2a, S2i, S2n
S3c, S3e, S3k, S3a, S3i, S3n, S3y, S3q, S3j, S3r
So we could write B3/S23 in correct but not canonical isotropic format as B3cekainyqjr/S2cekain3cekainyqjr...
dvgrn wrote:0) The last several iterations of LifeViewer and Golly interpret "B2a2e/S3" as "B2ae/S3", so we have a de facto standard interpretation established. Even if it's technically a lousy standard (though I don't think it is), we should be cautious about changing it at this late date. Here's plain-vanilla Life disguised as a non-canonical isotropic rule:
mniemiec wrote:I thought apgsearch 1.x didn't support non-totalistic rules.
mniemiec wrote:The problem with interpreting B2a2e as B2ae is that while it works fine for totally positive rules (i.e. B2x2y = B2(x|y)) and negative rules (i.e. B2-x2-y = B2-(x|y)), what consistent meaning could you apply when mixing both positive and negative rules, e.g. B2ae2-ca?
x = 3, y = 3, rule = B3/S2S3
obo$obo$3o!
x = 3, y = 3, rule = B3-a/S23-a
obo$obo$3o!
x = 3, y = 3, rule = B3-r/S23-r
obo$obo$3o!
x = 3, y = 3, rule = B3-ar/S23-ar
obo$obo$3o!
x = 3, y = 3, rule = B3-a3-r/S23-a3-r
obo$obo$3o!
#C -- illegal because a minus sign can only follow a digit
x = 3, y = 3, rule = B3-a-r/S23-a-r
obo$obo$3o!
// all valid rule letters
valid_rule_letters = "012345678ceaiknjqrytwz-" ;
// rule letters per neighbor count
rule_letters[0] = "ce" ;
rule_letters[1] = "ceaikn" ;
rule_letters[2] = "ceaiknjqry" ;
rule_letters[3] = "ceaiknjqrytwz" ;
// isotropic neighborhoods per neighbor count
static int entry0[2] = { 1, 2 } ;
static int entry1[6] = { 5, 10, 3, 40, 33, 68 } ;
static int entry2[10] = { 69, 42, 11, 7, 98, 13, 14, 70, 41, 97 } ;
static int entry3[13] = { 325, 170, 15, 45, 99, 71, 106, 102, 43, 101, 105, 78, 108 } ;
rule_neighborhoods[0] = entry0 ;
rule_neighborhoods[1] = entry1 ;
rule_neighborhoods[2] = entry2 ;
rule_neighborhoods[3] = entry3 ;
// bit offset for survival part of rule
survival_offset = 9 ;
// bit in letter bit mask indicating negative
negative_bit = 13 ;
// maximum number of letters per neighbor count
max_letters[0] = 0 ;
max_letters[1] = (int) strlen(rule_letters[0]) ;
max_letters[2] = (int) strlen(rule_letters[1]) ;
max_letters[3] = (int) strlen(rule_letters[2]) ;
max_letters[4] = (int) strlen(rule_letters[3]) ;
max_letters[5] = max_letters[3] ;
max_letters[6] = max_letters[2] ;
max_letters[7] = max_letters[1] ;
max_letters[8] = max_letters[0] ;
for (i = 0 ; i < survival_offset ; i++) {
max_letters[i + survival_offset] = max_letters[i] ;
}
// canonical letter order per neighbor count
static int order0[1] = { 0 } ;
static int order1[2] = { 0, 1 } ;
static int order2[6] = { 2, 0, 1, 3, 4, 5 } ;
static int order3[10] = { 2, 0, 1, 3, 6, 4, 5, 7, 8, 9 } ;
static int order4[13] = { 2, 0, 1, 3, 6, 4, 5, 7, 8, 10, 11, 9, 12 } ;
order_letters[0] = order0 ;
order_letters[1] = order1 ;
order_letters[2] = order2 ;
order_letters[3] = order3 ;
order_letters[4] = order4 ;
order_letters[5] = order3 ;
order_letters[6] = order2 ;
order_letters[7] = order1 ;
order_letters[8] = order0 ;
for (i = 0 ; i < survival_offset ; i++) {
order_letters[i + survival_offset] = order_letters[i] ;
}
// ...
// set rule from birth or survival string
void liferules::setRuleFromString(const char *rule, bool survival) {
// current and next character
char current ;
char next ;
// whether character normal or inverted
int normal = 1 ;
// letter index
char *letterindex = 0 ;
int lindex = 0 ;
int nindex = 0 ;
// process each character
while ( *rule ) {
current = *rule ;
rule++ ;
// find the index in the valid character list
letterindex = strchr((char*) valid_rule_letters, current) ;
lindex = letterindex ? int(letterindex - valid_rule_letters) : -1 ;
// check if it is a digit
if (lindex >= 0 && lindex <= 8) {
// determine what follows the digit
next = *rule ;
nindex = -1 ;
if (next) {
letterindex = strchr((char*) rule_letters[3], next) ;
if (letterindex) {
nindex = int(letterindex - rule_letters[3]) ;
}
}
// is the next character a digit or minus?
if (nindex == -1) {
setTotalistic(lindex, survival) ;
}
// check for inversion
normal = 1 ;
if (next == '-') {
rule++ ;
next = *rule ;
// invert following character meanings
normal = 0 ;
}
// process non-totalistic characters
if (next) {
letterindex = strchr((char*) rule_letters[3], next) ;
nindex = -1 ;
if (letterindex) {
nindex = int(letterindex - rule_letters[3]) ;
}
while (nindex >= 0) {
// set symmetrical
setSymmetrical(lindex, survival, nindex, normal) ;
// get next character
rule++ ;
next = *rule ;
nindex = -1 ;
if (next) {
letterindex = strchr((char*) rule_letters[3], next) ;
if (letterindex) {
nindex = int(letterindex - rule_letters[3]) ;
}
}
}
}
}
}
}
// ...
// set symmetrical neighborhood into 3x3 map
void liferules::setSymmetrical512(int x, int b) {
int y = x ;
int i = 0 ;
// process each of the 4 rotations
for (i = 0 ; i < 4 ; i++) {
rule3x3[y] = (char) b ;
y = rotateBits90Clockwise(y) ;
}
// flip
y = flipBits(y) ;
// process each of the 4 rotations
for (i = 0 ; i < 4 ; i++) {
rule3x3[y] = (char) b ;
y = rotateBits90Clockwise(y) ;
}
}
// set symmetrical neighborhood
void liferules::setSymmetrical(int value, bool survival, int lindex, int normal) {
int xorbit = 0 ;
int nindex = value - 1 ;
int x = 0 ;
int offset = 0 ;
// check for homogeneous bits
if (value == 0 || value == 8) {
setTotalistic(value, survival) ;
}
else {
// update the rulebits
if (survival) {
offset = survival_offset ;
}
rulebits |= 1 << (value + offset) ;
// reflect the index if in second half
if (nindex > 3) {
nindex = 6 - nindex ;
xorbit = 0x1ef ;
}
// update the letterbits
letter_bits[value + offset] |= 1 << lindex ;
if (!normal) {
// set the negative bit
letter_bits[value + offset] |= 1 << negative_bit ;
}
// lookup the neighborhood
x = rule_neighborhoods[nindex][lindex] ^ xorbit ;
if (survival) {
x |= 0x10 ;
}
setSymmetrical512(x, normal) ;
}
}
x = 3, y = 3, rule = B3-a3a/S2-e2e3-a3a
obo$obo$3o!
dvgrn wrote:LifeViewer and Golly have a consistent (in the sense of predictable and reproducible) interpretation of isotropic rulestrings, and I don't think there are any rulestring parsers currently in use that do anything else. Is there really a problem here, that won't be made significantly worse by any possible change at this point?
Apple Bottom wrote:dvgrn wrote:Is there really a problem here, that won't be made significantly worse by any possible change at this point?
Probably not, especially so long as people (read: Catagolue contributors, mostly) do the reasonable thing and don't use silly rulestrings just because it's possible. (Of course, as we all know, there's always people who you can't reasonably expect to behave reasonably.)
dvgrn wrote:I must admit I haven't been paying proper attention, though:
Are there any variant rulestrings that people have typed, or might actually type, by accident in good faith, that could result in their hauls going off into an annoying separate bin somewhere? Like b3-s23 (negative but no letters afterward) or s23b3, anything along those lines?
$ ./recompile.sh --rule b3-s23
Skipping updates; use --update to update apgluxe automatically.
Ensuring lifelib is up-to-date...
Symmetry unspecified; assuming C1.
Configuring rule b3-s23; symmetry C1
Error: b3-s23 is a non-canonical version of b3s23
Please re-run the code with the canonical rulestring:
./recompile.sh --rule b3s23
[...]
$ ./recompile.sh --rule s23b3
Skipping updates; use --update to update apgluxe automatically.
Ensuring lifelib is up-to-date...
Symmetry unspecified; assuming C1.
Configuring rule s23b3; symmetry C1
Invalid rulestring: s23b3 is not of the form:
bXsY
where X, Y are subsets of {0, 1, 2, ..., 8}, or:
gNbXsY
where N >= 3 is the number of states, or:
rNbWtXsYtZ
where 2 <= N <= 7 is the range and W,X,Y,Z are positive integers
$
$ ./recompile.sh --rule b3s2-e2e3
Skipping updates; use --update to update apgluxe automatically.
Ensuring lifelib is up-to-date...
Symmetry unspecified; assuming C1.
Configuring rule b3s2-e2e3; symmetry C1
Error: b3s2-e2e3 is a non-canonical version of b3s2e3
Please re-run the code with the canonical rulestring:
./recompile.sh --rule b3s2e3
[...]
$
dvgrn wrote:Are there any variant rulestrings that people have typed, or might actually type, by accident in good faith, that could result in their hauls going off into an annoying separate bin somewhere? Like b3-s23 (negative but no letters afterward) or s23b3, anything along those lines?
Apple Bottom wrote:dvgrn wrote:Are there any variant rulestrings that people have typed, or might actually type, by accident in good faith, that could result in their hauls going off into an annoying separate bin somewhere? Like b3-s23 (negative but no letters afterward) or s23b3, anything along those lines?
Not to my knowledge. In fact apgluxe at least seems to catch some of these...
...
On a side note, BTW, it also turns out that apgsearch's idea of how ambiguous rulestrings should be parsed matches my intuition, with later specifications of subconditions taking precedence over earlier ones:Code: Select allConfiguring rule b3s2-e2e3; symmetry C1
Error: b3s2-e2e3 is a non-canonical version of b3s2e3
Please re-run the code with the canonical rulestring:
./recompile.sh --rule b3s2e3
Users browsing this forum: gameoflifeboy and 3 guests