From 9ab64e9d8e19b92a7e34a3e41ea20c957c8f4ae1 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 24 Nov 2018 00:01:26 +0100 Subject: [PATCH] generators included --- generators/README.md | 14 +++ generators/bring.cpp | 122 ++++++++++++++++++ generators/macbeath.cpp | 132 ++++++++++++++++++++ patterngen.cpp => generators/patterngen.cpp | 0 generators/quartic.cpp | 105 ++++++++++++++++ generators/schmutz.cpp | 112 +++++++++++++++++ 6 files changed, 485 insertions(+) create mode 100644 generators/README.md create mode 100644 generators/bring.cpp create mode 100644 generators/macbeath.cpp rename patterngen.cpp => generators/patterngen.cpp (100%) create mode 100644 generators/quartic.cpp create mode 100644 generators/schmutz.cpp diff --git a/generators/README.md b/generators/README.md new file mode 100644 index 00000000..af08c95b --- /dev/null +++ b/generators/README.md @@ -0,0 +1,14 @@ +For completeness, this directory contains various programs used for generating various tables in HyperRogue. + +* Quotient space tables (in `hrmap_quotient` in `cell.cpp`) have been generated with `bring.cpp`, `schmutz.cpp`, `quartic.cpp`, `macbeath.cpp`, and (for Minimal) manually. + +* Pattern rules (in `patterns.cpp`) have been generated with patterngen.cpp. + +* Precomputed windmaps (`windcodes*` in `complex.cpp`) have been generated by the disabled code in `windmap::create()`. + +* Embedded font (`fonttable` in `nofont.cpp`) has been generated with `-DCAP_CREATEFONT=1`. + +* Vector graphics (`polydata[]` in `polygons.cpp`) have been generated in the Vector Graphics Editor. Press the Shift+S to generate the data in the required format. (Replace `ID` with `NEWSHAPE, id`.) + +Some of these programs are standalone, while some need to be compiled with HyperRogue. These programs are not maintained (they are written once and forgotten), so (in the latter case) +it is likely that they do no longer work; however, they are still included for reference. diff --git a/generators/bring.cpp b/generators/bring.cpp new file mode 100644 index 00000000..a7c3a744 --- /dev/null +++ b/generators/bring.cpp @@ -0,0 +1,122 @@ +// Bring's Surface generator +// Copyright (C) 2018 Zeno Rogue, see 'hyper.cpp' for details + +#include +#include +#include +#include +#include + +using namespace std; + +int isize(const auto x) { return x.size(); } + +int mul(int a, int b) { + int p = 0; + for(int i=0; i<3; i++) if((a>>i)&1) + for(int j=0; j<3; j++) if((b>>j)&1) + p ^= (1<<(i+j)); + + for(int z=4; z>=0; z--) + if(p&(8<> s5_elements; + +map, int> back; + +int multable[504][504]; + +int mpow(int a, int n) { + int z = a; + while(n > 1) z = multable[a][z], n--; + return z; + } + +int inset[504]; + +int main() { + array ar; + for(int i=0; i<5; i++) ar[i] = i; + + do { + back[ar] = isize(s5_elements); + s5_elements.push_back(ar); + } + while(next_permutation(ar.begin(), ar.end())); + + for(int a=0; a<120; a++) + for(int b=0; b<120; b++) { + array res; + for(int i=0; i<5; i++) + res[i] = s5_elements[a] [ s5_elements[b][i] ]; + multable[a][b] = back[res]; + } + + int id; + + for(int a=0; a<120; a++) + if(multable[a][a] == a) id = a; + + printf("id = %d\n", id); + + int xid = 0; + + int sols = 0; + + for(int R=0; R<120; R++) + for(int P=0; P<120; P++) { + if(P == 0 && mpow(R, 5) == id) printf("deg5 R\n"); + if(multable[P][P] != id) continue; + if(mpow(multable[R][P], 4) != id) continue; + if(mpow(R, 5) != id) continue; + xid++; + vector allels = {id}; + inset[id] = xid; + for(int i=0; i cellid; + array bycellid; + + for(int a=0; a<120; a++) cellid[a] = 0; + + int ncell = 0; + for(int a=0; a<120; a++) if(cellid[a] == 0) { + int b = a; + for(int s=0; s<5; s++) cellid[b] = ncell + s, bycellid[ncell + s] = b, b = multable[b][R]; + ncell += 5; + } + + printf("ncell = %d\n", ncell); + + for(int a=0; a<24; a++) { + printf("/* %03d */ ", a); + for(int b=0; b<5; b++) { + printf("%d, ", cellid[multable[bycellid[5*a+b]][P]]); + } + printf("\n"); + } + + return 0; + } + + printf("solutions = %d\n", sols); + + return 0; + } diff --git a/generators/macbeath.cpp b/generators/macbeath.cpp new file mode 100644 index 00000000..f347441d --- /dev/null +++ b/generators/macbeath.cpp @@ -0,0 +1,132 @@ +// Fricke-Macbeath Surface generator +// Copyright (C) 2018 Zeno Rogue, see 'hyper.cpp' for details + +#include +#include +#include +#include + +using namespace std; + +int isize(const auto x) { return x.size(); } + +int mul(int a, int b) { + int p = 0; + for(int i=0; i<3; i++) if((a>>i)&1) + for(int j=0; j<3; j++) if((b>>j)&1) + p ^= (1<<(i+j)); + + for(int z=4; z>=0; z--) + if(p&(8<> psl_elements; + +int multable_psl[504][504]; + +map, int> back; + +int mpow(int a, int n) { + int z = a; + while(n > 1) z = multable_psl[a][z], n--; + return z; + } + +int inset[504]; + +int main() { + for(int a=0; a<8; a++) { + for(int b=0; b<8; b++) printf("%d ", mul(a, b)); + printf("\n"); + } + + for(int a=0; a<8; a++) + for(int b=0; b<8; b++) + multable[a][b] = mul(a, b); + + for(int a=0; a<8; a++) + for(int b=0; b<8; b++) + for(int c=0; c<8; c++) + for(int d=0; d<8; d++) + if((multable[a][d] ^ multable[b][c]) == 1) { + array arr = { a, b, c, d}; + psl_elements.emplace_back(arr); + } + + printf("elements = %d\n", isize(psl_elements)); + + for(int a=0; a<504; a++) back[psl_elements[a]] = a; + + for(int a=0; a<504; a++) + for(int b=0; b<504; b++) { + auto pa = psl_elements[a]; + auto pb = psl_elements[b]; + array pc; + for(int s=0; s<4; s++) { + int s0 = s&2; + int s1 = s&1; + pc[s] = (multable[pa[s0]][pb[s1]] ^ multable[pa[s0^1]][pb[s1^2]]); + } + multable_psl[a][b] = back[pc]; + } + + int id; + + for(int a=0; a<504; a++) + if(multable_psl[a][a] == a) id = a; + + printf("id = %d\n", id); + + int xid = 0; + + for(int R=0; R<504; R++) + for(int P=0; P<504; P++) { + if(multable_psl[P][P] != id) continue; + if(mpow(multable_psl[R][P], 3) != id) continue; + if(mpow(R, 7) != id) continue; + xid++; + vector allels = {id}; + inset[id] = xid; + for(int i=0; i cellid; + array bycellid; + + for(int a=0; a<504; a++) cellid[a] = 0; + + int ncell = 0; + for(int a=0; a<504; a++) if(cellid[a] == 0) { + int b = a; + for(int s=0; s<7; s++) cellid[b] = ncell + s, bycellid[ncell + s] = b, b = multable_psl[b][R]; + ncell += 7; + } + + printf("ncell = %d\n", ncell); + + for(int a=0; a<72; a++) { + printf("/* %03d */ ", a); + for(int b=0; b<7; b++) { + printf("%d, ", cellid[multable_psl[bycellid[7*a+b]][P]]); + } + printf("\n"); + } + + return 0; + } + + return 0; + } diff --git a/patterngen.cpp b/generators/patterngen.cpp similarity index 100% rename from patterngen.cpp rename to generators/patterngen.cpp diff --git a/generators/quartic.cpp b/generators/quartic.cpp new file mode 100644 index 00000000..cb222937 --- /dev/null +++ b/generators/quartic.cpp @@ -0,0 +1,105 @@ +// this generates data for Klein's Quartic (-geo 0 -quartic) and Bolza surface (in -geo 7 -quartic) and 2x Bolza (-geo7 -quartic2) +// Copyright (C) 2018 Zeno Rogue, see 'hyper.cpp' for details + +#include "../init.cpp" + +using namespace hr; + +int qty; + +namespace hr { +cellwalker& operator += (cellwalker& cw, int spin); +cellwalker& operator += (cellwalker& cw, wstep_t); +} + +void recursive(cell *c, int col, int dir, int dbl) { + c->landparam = col; + c->mondir = dir; + c->monst = moButterfly; + if(S7 == 7) { + for(int i=0; i<7; i++) { + for(int j=3; j<5; j++) { + cellwalker cw(c, dir + i); + for(int u=0; u<4; u++) { + cw += wstep; + cw += j; + } + cw += -dir; + if(cw.c->landparam == -1) recursive(cw.c, col^dbl, dir, dbl); + } + } + } + if(S7 == 8) { + for(int i=0; i<8; i++) { + cellwalker cw(c, dir); + cw += i; + cw += wstep; + cw += 4; + cw += wstep; + cw += (4-i); +// if(cw.c->landparam == -1) recursive(cw.c, (col ^ 1)); + if(cw.c->landparam == -1) recursive(cw.c, col ^ dbl, cw.spin, dbl); + } + } + } + +void generate_quartic(bool dbl) { + celllister clgen(cwt.c, S7==7?10:8, 1000000, NULL); + int d; + for(cell *c1: clgen.lst) { c1->landparam = -1; d = celldist(c1); } + for(cell *c1: clgen.lst) if(c1->landparam == -1) { + recursive(c1, qty, 0, dbl); + qty++; + if(dbl) qty++; + } + vector colors; + for(cell *c1: clgen.lst) { + if(celldist(c1) >= d-1) continue; + if(c1->mov[c1->mondir]->landparam > c1->mov[c1->mondir ^ 4]->landparam) + c1->mondir ^= 4; + } + + if(0) for(cell *c1: clgen.lst) { + if(celldist(c1) >= d-2) continue; + vector connections; + cellwalker cw(c1, c1->mondir); + for(int i=0; ilandparam * S7 + (cwx.spin - cwx.c->mondir + MODFIXER) % S7); + cw += 1; + } + printf("/* %03d */", c1->landparam); + for(int i=0; ilandparam = colors[c1->landparam % qty]; + } + } + +int readArgs() { + using namespace arg; + + if(0) ; + else if(argis("-quartic")) { + PHASE(3); + start_game(); + generate_quartic(0); + } + else if(argis("-quartic2")) { + PHASE(3); + start_game(); + generate_quartic(1); + } + else return 1; + return 0; + } + +auto hook = addHook(hooks_args, 100, readArgs); + +// Bolza:: genus 2 => Euler characteristic -2 +// octagon: -2/6 +// ~> 6 octagons + diff --git a/generators/schmutz.cpp b/generators/schmutz.cpp new file mode 100644 index 00000000..52162e9b --- /dev/null +++ b/generators/schmutz.cpp @@ -0,0 +1,112 @@ +// Schmutz's Surface generator +// Copyright (C) 2018 Zeno Rogue, see 'hyper.cpp' for details + +#include +#include +#include +#include +#include + +using namespace std; + +void dualize(vector& t) { + int N = t.size(); + /* + printf("N = %d\n", N); + + printf("pre dual:\n"); + for(int a=0; a tmap(N, -1); + vector trmap(N, -1); + int s = 0; + for(int i=0; i %d\n", oj, j); + } + if(j != i) printf("not equal\n"), exit(1); + // printf("OK\n"); + } + // for(int a: tmap) printf("%d ", a); printf("\n"); + // for(int a: trmap) printf("%d ", a); printf("\n"); + vector res(N, -1); + for(int i=0; i triangles; + + for(int a=0; a<12; a++) { + triangles.emplace_back(3 * ((a+1) % 12) + 1); + triangles.emplace_back(3 * ((a+11) % 12)); + triangles.emplace_back(36 + (a%4) * 3 + 2 - (a/4)); + } + + for(int a=0; a<12; a++) + triangles.emplace_back(0); + + for(int a=0; a<36; a++) if(triangles[a] >= 36) triangles[triangles[a]] = a; + + dualize(triangles); + + for(int a=0; a<48; a++) { + if(a % 12 == 0) printf("\n"); + printf("%3d, ", triangles[a]); + } + + printf("\n"); + + triangles.clear(); + + for(int a=0; a<12; a++) { + triangles.emplace_back(3 * ((a+1) % 12) + 1); + triangles.emplace_back(3 * ((a+11) % 12)); + triangles.emplace_back(36 + 3 * a); + } + + for(int a=0; a<12; a++) { + triangles.emplace_back(3 * a + 2); + triangles.emplace_back(36 + (3 * a + 36 - 15 + 2) % 36); + triangles.emplace_back(36 + (3 * a + 36 + 15 + 1) % 36); + } + + dualize(triangles); + + for(int a=0; a<12*2*3; a++) { + if(a % 12 == 0) printf("\n"); + printf("%3d, ", triangles[a]); + } + + printf("\n"); + + return 0; + }