int mostSurvives(LifeList *pattern, LifeList *perturb, int transl, int steps) { int i; copyLifeList(pattern, &tmp); copyLifeList(perturb, &spread1); spread(&spread1, 1); for (i=0; i<steps; i++) { generate(&tmp); } if ( matchLifeList(&tmp, perturb, transl) >= perturb->ncells-4 ) return 1; return 0; }
int survives(LifeList *pattern, LifeList *perturb, int transl, int steps) { int i; copyLifeList(pattern, &tmp); copyLifeList(perturb, &spread1); spread1.ncells = removeGreaterThan(spread1.cellList, spread1.ncells, 1); for (i=0; i<steps; i++) { generate(&tmp); if ( matchLifeList(&tmp, &spread1, transl) < spread1.ncells ) // || matchLifeList (&tmp, perturb, transl) < perturb->ncells-6 ) return 0; } return 1; }
void cumulativeImage(LifeList *cells, LifeList *cumulative, int ngens) { int i; copyLifeList(cells, cumulative); for (i=1; i<ngens; i++) { generate(cells); mergeLifeLists(cumulative, cells, 0); } }
int independentUpTo(LifeList *cells, LifeList *cumulative, LifeList *working, int ngens) { int nClusters; copyLifeList(cells, working); cumulativeImage(working, cumulative, ngens); nClusters = findComponents(cumulative, working, 2); getLifeListValues(cells, working); return nClusters; }
int restored(LifeList *pattern, LifeList *perturb, int transl, int steps) { int i,damaged, lastsfor; copyLifeList(perturb, &spread1); spread(&spread1, 1); copyLifeList(pattern, &tmp); damaged = 0; lastsfor = 0; for (i=0; i<steps; i++) { generate(&tmp); if ( matchLifeList(&tmp, perturb, transl) == perturb->ncells && matchLifeList(&tmp, &spread1, transl) == perturb->ncells ) { if (damaged) lastsfor++; if (lastsfor>=10) return 1; } else { damaged = 1; lastsfor = 0; } } return 0; }
int interact(LifeList *pat1, LifeList *pat2, int transl) { /* both pat1 and pat2 are generated one step */ copyLifeList(pat1, &both); mergeLifeLists(&both, pat2, transl); generate(pat1); generate(pat2); generate(&both); return !( both.ncells == pat1->ncells + pat2->ncells && pat1->ncells == countMatch(pat1->cellList, pat1->ncells, both.cellList, both.ncells) && pat2->ncells == matchLifeList(&both, pat2, transl) ); }
int simpleSS(LifeList *cells, LifeList *working) { int i, transl; /* checks if pattern in cells is a simple (period 4) spaceship */ (void) firstZero(cells->cellList,cells->ncells); copyLifeList(cells, working); for (i=0; i<4; i++) generate(working); transl = firstZero(working->cellList, working->ncells); if (cells->ncells == working->ncells && !compare(working->cellList, cells->cellList, cells->ncells)) { return transl; } else return packtrans(-255, -255); }
OscillatorDesc simpleOscillation(LifeList *cells, LifeList *working, int testUpTo) { int i, initTransl, transl; OscillatorDesc osc; /* Looks for first "simple" oscillation of a pattern up to testUpTo. This includes a translation, but no other coordinate transformation. Returns the period and translation (returns -1 if no oscillation found) */ initTransl = firstZero(cells->cellList,cells->ncells); copyLifeList(cells, working); for (i=1; i<=testUpTo; i++) { generate(working); if (cells->ncells == working->ncells) { transl = firstZero(working->cellList, working->ncells); if (!compare(working->cellList, cells->cellList, cells->ncells)) break; copyList(working->cellList, working->ncells, working->cellList, transl); } } copyList(cells->cellList, cells->ncells, cells->cellList, initTransl); osc.testedUpTo = testUpTo; if (i> testUpTo) osc.period = -1; else osc.period = i; osc.T.flipxF = osc.T.flipyF = osc.T.transposeF = 0; osc.T.translateBy = transl; return osc; }
main(int argc, char *argv[]) { static LifeList cells; static LifeList matchcells; static LifeList outcells; int i,j,n=0; int gens=500; int x,y; int match; int pos; int count[240]; int least= 0; int fail; int damaged; int restored; int prodcells; int restorefilter=10; char outpat[100000]; History hist; int period, repetitions; Cell lifetrail[5000]; static char nextpat[10000]; int ncls; initLifeList(&cells); initLifeList(&matchcells); initLifeList(&outcells); if (argc>2) { sscanf(argv[2], "%d", &restorefilter); } while(gets(nextpat)) { for (i=0; i<240; i++) { count[i] = i; } getpat(nextpat, &cells); copyLifeList(&cells, &matchcells); if (argc>1) { for (i=0; argv[1][i]; i++) { matchcells.ncells = removeIfEquals(matchcells.cellList, matchcells.ncells, argv[1][i]); } } fail=0; damaged=0; restored=0; for (i=0; i<gens; i++) { generate(&cells); // printf("%d %d %d %d\n", i, fail, damaged, restored); count[i%240] = cells.ncells; if (cells.ncells == 0) break; match = 1; for (j=0; j<180; j++) { if (count[j] != count[j+60]) { match = 0; break; } } if (match) break; if ( matchLifeList(&cells, &matchcells, 0) < matchcells.ncells) { fail++; restored=0; } else { prodcells = cells.ncells - matchcells.ncells; copyLifeList(&cells, &outcells); restored++; if (restored>restorefilter) { if (fail>damaged) damaged=fail; fail = 0; } } if (fail>150) break; } if (damaged) { fflush(stdout); removeLifeList(&outcells, &matchcells, 0); makeString(outcells.cellList, outcells.ncells, outpat); printf("%s %d %d %d %d %s\n", nextpat, damaged, fail, i-fail, prodcells, outpat); } } }
void perturbEnum(LifeList *seed, LifeList *perturbs, int nperturbs, int depth, int maxDepth, int mingen, int maxgencurr, int maxgenall, int maxvanish) { int i, naligns; int iperturb, thisgen; for (iperturb=0; iperturb<nperturbs; iperturb++) { if(depth == 0 && maxDepth > 1) fprintf(stderr, "Working with perturber #%d\n", iperturb+1); copyLifeList(seed, reaction+depth); setValues(reaction[depth].cellList, reaction[depth].ncells, 1); naligns=placeNewPerturbor(reaction+depth, perturbs, perturbPlace, depth, iperturb, mingen, maxgencurr, aligns); setupPerturbors(perturbs, perturbPlace, depth, &justPerturbs, reaction+depth); for (thisgen=0; thisgen<mingen; thisgen++) generate(reaction+depth); for (; thisgen<maxgencurr; thisgen++) { for (i=0; i<naligns; i++) { int j; int tvanish = maxvanish; int oldcount; assert((aligns-alignstore)+i < 100000); if (aligns[i].value==thisgen && (depth<=0 || ptbPrecedes(perturbGen[depth-1], perturbPlace[depth-1].value, perturbPlace[depth-1].position, thisgen, iperturb, aligns[i].position)) ) { copyLifeList(reaction+depth, &tmp); justPerturbs.ncells=0; for (j=0; j<depth; j++) { mergeLifeLists(&justPerturbs, perturbs+perturbPlace[j].value, perturbPlace[j].position); } mergeLifeLists(&tmp, perturbs+iperturb, aligns[i].position); oldcount=justPerturbs.ncells; mergeLifeLists(&justPerturbs, perturbs+iperturb, aligns[i].position); // if (iperturb==8) printf("chose a block %d %d\n", perturbs[iperturb].ncells, countGreaterThan(perturbs[iperturb].cellList, perturbs[iperturb].ncells, 1) ); if ( countGreaterThan(perturbs[iperturb].cellList, perturbs[iperturb].ncells, 1) == perturbs[iperturb].ncells) tvanish--; if (tvanish>=0 && oldcount+perturbs[iperturb].ncells == justPerturbs.ncells && survives(&tmp, &justPerturbs, 0, 15)) { if (depth >= maxDepth) { if (restored(&tmp, &justPerturbs, 0, 50)) { copyLifeList(seed, &tmp); mergeLifeLists(&tmp, &justPerturbs, 0); makeString(tmp.cellList, tmp.ncells, out); // outTr(perturbPlace[0].position); // outTr(perturbPlace[1].position); // outTr(aligns[i].position); printf("%s %d\n", out, thisgen); /* printf("%d %d %d ", perturbPlace[0].position, perturbPlace[0].value, perturbGen[0]); printf("%d %d %d\n", aligns[i].position, iperturb, aligns[i].value); */ fflush(stdout); } } else { perturbPlace[depth].position= aligns[i].position; perturbPlace[depth].value= iperturb; perturbGen[depth]= thisgen; aligns+=naligns; perturbEnum(seed, perturbs, nperturbs, depth+1, maxDepth, thisgen, maxgenall, maxgenall, tvanish); aligns-=naligns; } } } } generate(reaction+depth); } } }
int placeNewPerturbor(LifeList *seed, LifeList *perturbs, Cell *placed, int nplaced, int newperturb, int initialGen, int finalGen, Cell *aligns) { int i, j; int nconv, nold, naligns, nelim; copyLifeList(perturbs+newperturb, &thisperturb); copyLifeList(&thisperturb, &spread1); spread(&spread1, 1); copyLifeList(&spread1, &spread2); spread(&spread2, 1); removeLifeList(&spread2, &spread1, 0); copyLifeList(seed, &cells); setupPerturbors(perturbs, placed, nplaced, &perturbcells, &cells); naligns=0; for (i=0; i<finalGen; i++) { nconv=convolve(spread2.cellList, spread2.ncells, cells.cellList, cells.ncells, &convolution, &scratch1, &scratch2, makeWorkSpace); makeWorkSpace(spread1.ncells*cells.ncells); nold=convolve(spread1.cellList, spread1.ncells, cells.cellList, cells.ncells, &oldAlignments, &scratch1, &scratch2, makeWorkSpace); nconv=subtractLists(oldAlignments, nold, convolution, nconv); nconv=subtractLists(aligns, naligns, convolution, nconv); setValues(convolution, nconv, i); nelim=0; for (j=0; j<nconv; j++) { copyLifeList(&cells, &tmp); intersectLifeLists(&tmp, &spread2, convolution[j].position); if (interact(&tmp, &thisperturb, convolution[j].position)) { convolution[nelim++]=convolution[j]; } } makeWorkSpace(nelim + naligns); naligns=combineLists(convolution, nelim, aligns, naligns, scratch1); copyList(scratch1, naligns, aligns, 0); if (i == 0) { setValues(oldAlignments, nold, -1); makeWorkSpace(nold + naligns); naligns=combineLists(oldAlignments, nold, aligns, naligns, scratch1); copyList(scratch1, naligns, aligns, 0); } generate(&cells); if (broken(cells.cellList, cells.ncells, perturbcells.cellList, perturbcells.ncells)) break; } naligns=removeLessThan(aligns, naligns, initialGen); return naligns; }
main(int argc, char *argv[]) { static LifeList cells; static LifeList matchcells; static LifeList boundarycells; static LifeList intercells; static LifeList outcells; int i,j,n=0; int gens=500; int x,y; int match; int pos; int count[240]; int least= 0; int fail; int damaged; int restored; int firstgen; int maxgen; int survivegen; int restorefilter=10; int maxrecoverytime=20; char interpat[100000]; char outpat[100000]; History hist; int period, repetitions; Cell lifetrail[50000]; static char nextpat[100000]; int ncls; initLifeList(&cells); initLifeList(&matchcells); initLifeList(&boundarycells); initLifeList(&intercells); initLifeList(&outcells); if (argc>2) { sscanf(argv[2], "%d", &restorefilter); } while(gets(nextpat)) { for (i=0; i<240; i++) { count[i] = i; } getpat(nextpat, &cells); copyLifeList(&cells, &matchcells); if (argc>1) { for (i=0; argv[1][i]; i++) { matchcells.ncells = removeIfEquals(matchcells.cellList, matchcells.ncells, argv[1][i]); } } copyLifeList(&matchcells, &boundarycells); spread(&boundarycells, 1); fail=0; damaged=0; restored=0; firstgen=0; maxgen=0; survivegen=0; for (i=0; i<gens; i++) { // printf("%d %d %d %d\n", i, fail, damaged, restored); count[i%240] = cells.ncells; if (cells.ncells == 0) break; match = 1; for (j=0; j<180; j++) { if (count[j] != count[j+60]) { match = 0; break; } } if (match) break; if ( matchLifeList(&cells, &matchcells, 0) < matchcells.ncells || matchLifeList(&cells, &boundarycells, 0) != matchcells.ncells) { fail++; restored=0; if (firstgen == 0) { firstgen = i; maxgen = i + restorefilter + maxrecoverytime; } } else { restored++; survivegen = i; if (restored>restorefilter) { if (restored == restorefilter + 1) { copyLifeList(&cells, &intercells); copyLifeList(&cells, &outcells); } if (i <= maxgen) { copyLifeList(&cells, &outcells); } if (fail>damaged) damaged=fail; fail = 0; firstgen = 0; } } if (fail>150) break; generate(&cells); } if (damaged) { fflush(stdout); removeLifeList(&outcells, &matchcells, 0); makeString(outcells.cellList, outcells.ncells, outpat); removeLifeList(&intercells, &matchcells, 0); makeString(intercells.cellList, intercells.ncells, interpat); printf("%s %d %s %s\n", nextpat, survivegen, interpat, outpat); } } }