Commit fc7d2f90 authored by Adam P. Goucher's avatar Adam P. Goucher

Escaping glider detection

parent fbf1c7c9
Pipeline #46085748 passed with stages
in 8 minutes and 4 seconds
#ifndef LIFELIB_VERSION /*
__version__=[x.replace('"', '') for x in '''
*/
#define LIFELIB_VERSION "ll2.1.13"
#define LIFELIB_VERSION "ll2.1.14"
// '''.split() if ('ll' in x)][0][2:]
#endif
const static uint8_t __gdirections[] __attribute__((aligned(64))) = {0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
template<int H, int K = 2>
struct VTile {
......@@ -103,6 +124,17 @@
}
inline static bool unsafeBoundary(const uint64_t *y) {
if (y[0] | y[1] | y[2] | y[3]) { return true; }
if (y[H/2 + K - 4] | y[H/2 + K - 3] | y[H/2 + K - 2] | y[H/2 + K - 1]) { return true; }
uint64_t z = 0;
for (int i = 4; i < H/2 + K - 4; i += 2) { z |= (y[i] | y[i+1]); }
return (z & 0xff0000ffff0000ffull);
}
int countPopulation(upattern<VTile<H,K>, 32 - 2*K, H>* owner) {
// Check memoized value:
......@@ -115,6 +147,30 @@
population = countpop64((uint64_t *) (d + K));
owner->population += population;
currentflags &= (~1);
if (population != 5) { return population; }
int ext = owner->is_extremal(coords);
if ((ext == 0) || unsafeBoundary((uint64_t *) d)) { return population; }
int i = 0;
for (i = 8; i < H + 2*K - 8; i++) {
if (d[i]) { break; }
}
uint32_t shadow = d[i] | d[i+1] | d[i+2];
int tzeroes = __builtin_ctz(shadow);
if ((shadow >> tzeroes) != 7) { return population; }
uint32_t signature = (d[i] >> tzeroes) | (d[i+1] >> (tzeroes - 3)) | (d[i+2] >> (tzeroes - 6));
if (ext & __gdirections[signature]) {
// remove glider:
d[i] = 0; d[i+1] = 0; d[i+2] = 0;
population = 0;
owner->glider_count += 1;
}
return population;
}
......
......@@ -56,6 +56,13 @@ namespace apg {
uint64_t tilesProcessed;
uint64_t gensElapsed;
int population;
int extremal_mask;
int glider_count;
int64_t max_xpy;
int64_t min_xpy;
int64_t max_xmy;
int64_t min_xmy;
T* coords2ptr(int64_t x, int64_t w) {
// Returns a pointer to tile x + omega*w.
......@@ -81,6 +88,9 @@ namespace apg {
torus_height = 0;
lastmant = 1;
population = 0;
extremal_mask = 0;
glider_count = 0;
max_xpy = 0; min_xpy = 0; max_xmy = 0; min_xmy = 0;
}
upattern(int width, int height) {
......@@ -91,6 +101,9 @@ namespace apg {
torus_height = height / H;
lastmant = 1;
population = 0;
extremal_mask = 0;
glider_count = 0;
max_xpy = 0; min_xpy = 0; max_xmy = 0; min_xmy = 0;
if ((width == 0) || (height == 0)) { return; }
......@@ -108,6 +121,19 @@ namespace apg {
}
}
int is_extremal(uint64_t x) {
int ext = 0;
int64_t tx = (x & 0xffffffffu) - 0x80000000u;
int64_t tw = (x >> 32) - 0x80000000u;
int64_t xpy = tx * W - (tw * (H + W/2));
int64_t xmy = tx * W + (tw * (H - W/2));
ext |= ((xpy >= max_xpy) ? 1 : 0);
ext |= ((xpy <= min_xpy) ? 2 : 0);
ext |= ((xmy >= max_xmy) ? 4 : 0);
ext |= ((xmy <= min_xmy) ? 8 : 0);
return (ext & extremal_mask);
}
T* getNeighbour(T* sqt, int i) {
T* y = sqt->neighbours[i];
if (!y) {
......@@ -116,6 +142,14 @@ namespace apg {
y->coords = x;
y->neighbours[(i + 3) % 6] = sqt;
sqt->neighbours[i] = y;
int64_t tx = (x & 0xffffffffu) - 0x80000000u;
int64_t tw = (x >> 32) - 0x80000000u;
int64_t xpy = tx * W - (tw * (H + W/2));
int64_t xmy = tx * W + (tw * (H - W/2));
max_xpy = (xpy > max_xpy) ? xpy : max_xpy;
min_xpy = (xpy < min_xpy) ? xpy : min_xpy;
max_xmy = (xmy > max_xmy) ? xmy : max_xmy;
min_xmy = (xmy < min_xmy) ? xmy : min_xmy;
}
return y;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment