diff --git a/devmods/honeycomb-generator.cpp b/devmods/honeycomb-generator.cpp new file mode 100644 index 00000000..2666e390 --- /dev/null +++ b/devmods/honeycomb-generator.cpp @@ -0,0 +1,365 @@ +/** + +Honeycomb data generator. + +Usage: + +./hyper -geo 534h -tcano honeycomb-534.dat -quit +./hyper -geo 535h -tcano honeycomb-535.dat -quit +./hyper -geo 435h -tcano honeycomb-435.dat -quit + +You need to change the value of XS7 to 6 (for 435) or 12 (for others) + +*/ + +#include "zlib.h" +#include "../hyper.h" + +namespace hr { + +map > rules; + +#define XS7 12 +#define FV master->fiftyval + +auto dis = [] (int i, char init='a') { return s0 + char(init + i); }; + +int get_id(cell *c) { + if(geometry == gSpace535) return 0; + return c->master->fieldval; + } + +string find_path(cell *x, cell *y, int steps) { + if(x->FV != y->FV) { + println(hlog, x, y, " steps=", steps, " d=", x->FV, " vs ", y->FV); + exit(3); + } + if(x == y) return ""; + if(steps == 0) return "?"; + for(int i=0; imove(i) && x->move(i)->FV < x->FV) + for(int j=0; jmove(j) && y->move(j)->FV < y->FV) { + string ch = find_path(x->move(i), y->move(j), steps-1); + if(ch == "?") continue; + return dis(i) + ch + dis(y->c.spin(j)); + } + return "?"; + } + +string find_path(cell *x, cell *y) { + if(x == y) return ""; + + for(int steps=0;; steps++) { + string f = find_path(x, y, steps); + if(f != "?") return f; + } + } + +vector> rule_list; + +struct ext_nei_rules_t { + vector from, dir, original; + }; + +map ext_nei_rules; + +set visi; + +void listnear(cell *c, ext_nei_rules_t& e, const transmatrix& T, int id) { + visi.insert(c); + int a = 0, b = 0; + for(int i=0; iadj(c, i); + for(auto v: reg3::vertices_only) for(auto w: reg3::vertices_only) + if(hdist(v, U*w) < 1e-3) ok = true; + if(!ok) continue; + cell *c1 = c->cmove(i); + int id1 = isize(e.from); + e.from.push_back(id); + e.dir.push_back(i); + a++; + e.original.push_back(!visi.count(c1)); + if(e.original.back()) { + b++; + listnear(c1, e, U, id1); + } + } + } + +void construct_rules(cell *c, ext_nei_rules_t& e) { + visi.clear(); + e.from = {-1}; + e.dir = {-1}; + e.original = {1}; + listnear(c, e, Id, 0); + int orgc = 0; + for(auto i: e.original) orgc += i; + println(hlog, "id ", get_id(c), " list length = ", isize(e.original), " original = ", orgc); + } + +void fix_dist(cell *a, cell *b) { + if(a->FV > b->FV+1) { + a->FV = b->FV+1; + forCellEx(c, a) fix_dist(a, c); + } + if(b->FV > a->FV+1) { + b->FV = a->FV+1; + forCellEx(c, b) fix_dist(b, c); + } + } + +string generate_ext_nei(cell *c) { + int fv = get_id(c); + auto& e = ext_nei_rules[fv]; + if(e.from.empty()) construct_rules(c, e); + vector ext_nei = {c}; + for(int i=1; icmove(e.dir[i]); + fix_dist(last, next); + ext_nei.push_back(next); + } + string res; + for(int i=0; iFV - c->FV); + return its(fv) + ":" + res; + } + +set candidates; +vector candidates_list; +map id_of; +vector rep_of; + +int number_states = 0; + +vector > child_rules; + +vector > side_rules; + +void add_candidate(cell *c) { + if(candidates.count(c)) return; + candidates.insert(c); + candidates_list.push_back(c); + } + +void test_canonical(string fname) { + if(S7 != XS7) { println(hlog, "fix XS7=", S7); exit(4); } + start_game(); + cell *c0 = cwt.at; + add_candidate(c0); + + array empty; + for(auto& e: empty) e = -1; + println(hlog, "empty = ", empty); + + for(int i=0; icmove(i)); + } + } + + child_rules.resize(number_states, empty); + + println(hlog, "found ", its(number_states), " states"); + fflush(stdout); + + for(int i=0; imove(a); + if(c1->FV <= c->FV) continue; + for(int b=0; bmove(b); + if(c2->FV != c->FV) continue; + if(c2 == c) { + child_rules[i][a] = id_of[generate_ext_nei(c1)]; + } + break; + } + continue; + } + } + + int root = 0; + + if(true) { + + println(hlog, "original rules: ", child_rules); + fflush(stdout); + + vector ih(number_states, 0); + + int lqids = 0; + + for(int a=0; a<100; a++) { + set> found; + vector> v(number_states); + map, int> ids; + for(int i=0; i res; + for(int d=0; dmove(a); + if(!c1) continue; + if(c1->FV < c->FV && !cpar) cpar = c1, a0 = a; + } + + for(int a=0; amove(a); + if(!c1) continue; + bool is_child = false; + cell* c2 = nullptr; + int dir = 0; + + if(c1->FV >= c->FV) { + for(int b=0; bmove(b); + if(!c2) continue; + if(c2->FV >= c1->FV) continue; + dir = c1->c.spin(b); + break; + } + } + + is_child = (c2 == c); + bool was_child = child_rules[id][a] >= 0; + + if(is_child ^ was_child) { + println(hlog, "id=", id, " a=", a); + println(hlog, "is_child = ", is_child); + println(hlog, "was_child = ", was_child); + println(hlog, "c fv = ", c->FV); + println(hlog, "c1 fv = ", c1->FV, " [", a, "]"); + if(c2 == nullptr) { println(hlog, "c2 missing"); } + else + println(hlog, "c2 fv = ", c2->FV, " [", c2->c.spin(dir), "]"); + println(hlog, c, "->", c1, "->", c2); + fflush(stdout); + + cell *r = rep_of[id]; + println(hlog, r, " at ", r->FV); + cell *r1 = r->move(a); + if(!r1) { println(hlog, "r1 missing"); continue; } + println(hlog, r1, " at ", r1->FV); + for(int a=0; amove(a)) println(hlog, a, ":", r1->move(a), " at ", r1->move(a)->FV); + fflush(stdout); + exit(3); + } + + if(is_child) continue; + + string solu; + + if(c1->FV < c->FV) + solu = dis(a0, 'A') + find_path(cpar, c1); + else if(c1->FV == c->FV) + solu = dis(a0, 'A') + find_path(cpar, c2) + dis(dir); + else + solu = find_path(c, c2) + dis(dir); + + auto& sr = side_rules[id][a]; + + if(sr != "" && sr != solu) { + println(hlog, "conflict: ", solu, " vs ", sr); + if(isize(sr) < isize(solu)) continue; + } + + sr = solu; + + continue; + } + } + + println(hlog, side_rules); + + string side_data; + for(auto& a: side_rules) for(auto&b :a) if(b != "") side_data += b + ","; + println(hlog, side_data); + + vector data; + for(auto& a: child_rules) for(auto i:a) data.push_back(i); + + shstream ss; + + auto& fp = currfp; + hwrite_fpattern(ss, fp); + + hwrite(ss, root); + + println(hlog, "copy data"); + hwrite(ss, data); + println(hlog, "copy side_data"); + hwrite(ss, side_data); + + println(hlog, "compress_string"); + string s = compress_string(ss.s); + + fhstream of(fname, "wb"); + print(of, s); + } + +auto fqhook = + addHook(hooks_args, 100, [] { + using namespace arg; + + if(0) ; + else if(argis("-tcano")) { + shift(); test_canonical(args()); + } + else return 1; + return 0; + }); + +} + +// 1 + 12 + 30 + 20 = 55 diff --git a/reg3.cpp b/reg3.cpp index 32f7efe7..8265d35f 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -592,6 +592,7 @@ EX namespace reg3 { h.cdata = NULL; h.alt = NULL; h.distance = 0; + h.fiftyval = 0; h.fieldval = 0; h.c7 = newCell(S7, origin); if(sphere) spherecells.push_back(h.c7); @@ -774,6 +775,7 @@ EX namespace reg3 { created->zebraval = hrand(10); created->fieldval = fv; created->distance = parent->distance + 1; + created->fiftyval = 9999; fixmatrix(T); reg_gmatrix[created] = make_pair(alt, T); altmap[alt].emplace_back(created, T);