32 for (
unsigned i = 2; i <= n; i++)
41 for (
unsigned i = 1; i < n; i++) {
42 for (
unsigned j = i + 1; j <= n; j++) {
50 fprintf(stderr,
"Warning: degenerate circle of %u vertices\n", n);
55 for (
unsigned i = 1; i < n; i++)
62 fprintf(stderr,
"Warning: degenerate star of %u vertices\n", n);
67 for (
unsigned i = 2; i <= n; i++)
73 fprintf(stderr,
"Warning: degenerate wheel of %u vertices\n", n);
80 for (
unsigned i = 2; i < n; i++)
86 for (
unsigned i = 1; i <= dim1; i++) {
87 for (
unsigned j = 1; j <= dim2; j++) {
94 for (
unsigned i = 1, n = 0; i <= dim1; i++) {
95 for (
unsigned j = 1; j < dim2; j++) {
96 ef( n + j, n + j + 1);
102 for (
unsigned i = 1; i <= dim2; i++) {
103 for (
unsigned j = 1; j < dim1; j++) {
104 ef( dim2 * (j - 1) + i, dim2 * j + i);
106 ef( i, dim2 * (dim1 - 1) + i);
112 for (
unsigned i = 0; i < dim1; i++) {
113 for (
unsigned j = 0; j < dim2; j++) {
114 unsigned li = (i + t1) % dim1;
115 unsigned lj = (j + 1) % dim2;
116 ef (i+j*dim1+1, li+lj*dim1+1);
119 lj = (j + t2) % dim2;
120 ef(i+j*dim1+1, li+lj*dim1+1);
126 for (
unsigned i = 1, n = 0; i <= dim1; i++) {
127 for (
unsigned j = 1; j < dim2; j++) {
128 ef( n + j, n + j + 1);
130 ef( n + 1, n + dim2);
134 for (
unsigned i = 1; i <= dim2; i++) {
135 for (
unsigned j = 1; j < dim1; j++) {
136 ef( dim2 * (j - 1) + i, dim2 * j + i);
141#define OUTE(h) if (tl < (hd=(h))) ef( tl, hd)
145 for (
unsigned i = 0; i < dim1; i++)
146 for (
unsigned j = 0; j < dim2; j++) {
148 const unsigned tl = i * dim2 + j + 1;
151 && (!partial || j < 2 * dim2 / 6 || j >= 4 * dim2 / 6
152 || i <= 2 * dim1 / 6 || i > 4 * dim1 / 6)) {
153 ef(tl, i * dim2 + j + 2);
156 ef(tl, (i + 1) * dim2 + j + 1);
158 if (connect_corners == 1) {
159 if (i == 0 && j == 0) {
160 OUTE((dim1 - 1) * dim2 + dim2);
161 }
else if (i + 1 == dim1 && j == 0) {
163 }
else if (i == 0 && j + 1 == dim2) {
164 OUTE((dim1 - 1) * dim2 + 1);
165 }
else if (i + 1 == dim1 && j + 1 == dim2) {
168 }
else if (connect_corners == 2) {
169 if (i == 0 && j == 0) {
171 }
else if (i + 1 == dim1 && j == 0) {
172 OUTE((dim1 - 1) * dim2 + dim2);
173 }
else if (i == 0 && j + 1 == dim2) {
175 }
else if (i + 1 == dim1 && j + 1 == dim2) {
176 OUTE((dim1 - 1) * dim2 + 1);
183 const double n = (pow(nary, depth) - 1) / (nary - 1);
186 for (
unsigned i = 1; i <= n; i++) {
187 for (
unsigned j = 0; j < nary; j++) {
194 assert(depth <
sizeof(
unsigned) * CHAR_BIT);
195 const unsigned n = (1u << depth) - 1;
197 for (
unsigned i = 1; i <= n; i++) {
206static void free_vtx(
vtx_data data) {
213static void append(vtx_datas_t *
graph,
size_t index,
unsigned ref) {
225 unsigned depth, vtx_datas_t *
graph) {
226 static unsigned last_used_node_name = 3;
229 const unsigned v4 = ++last_used_node_name;
230 const unsigned v5 = ++last_used_node_name;
231 const unsigned v6 = ++last_used_node_name;
239 append(
graph, v1, v2);
240 append(
graph, v1, v3);
242 append(
graph, v2, v1);
243 append(
graph, v2, v3);
245 append(
graph, v3, v1);
246 append(
graph, v3, v2);
250 vtx_datas_t
graph = {.dtor = free_vtx};
258 for (
size_t j = 0; j <
LIST_SIZE(g); j++) {
259 const unsigned nghbr =
LIST_GET(g, j);
260 if (i < nghbr) ef( i, nghbr);
268 unsigned depth, vtx_datas_t *
graph) {
269 static unsigned last_used_node_name = 4;
272 const unsigned v5 = ++last_used_node_name;
273 const unsigned v6 = ++last_used_node_name;
274 const unsigned v7 = ++last_used_node_name;
275 const unsigned v8 = ++last_used_node_name;
276 const unsigned v9 = ++last_used_node_name;
277 const unsigned v10 = ++last_used_node_name;
285 append(
graph, v1, v2);
286 append(
graph, v1, v3);
287 append(
graph, v1, v4);
289 append(
graph, v2, v1);
290 append(
graph, v2, v3);
291 append(
graph, v2, v4);
293 append(
graph, v3, v1);
294 append(
graph, v3, v2);
295 append(
graph, v3, v4);
297 append(
graph, v4, v1);
298 append(
graph, v4, v2);
299 append(
graph, v4, v3);
303 vtx_datas_t
graph = {.dtor = free_vtx};
311 for (
size_t j = 0; j <
LIST_SIZE(g); j++) {
312 const unsigned nghbr =
LIST_GET(g, j);
313 if (i < nghbr) ef( i, nghbr);
321 assert(
dim <
sizeof(
unsigned) * CHAR_BIT);
322 const unsigned n = 1u <<
dim;
324 for (
unsigned i = 0; i < n; i++) {
325 for (
unsigned j = 0; j <
dim; j++) {
326 const unsigned neighbor = (i ^ (1u << j)) + 1;
341 for (
unsigned i = 2; i < sz; i++) {
342 for (
unsigned j = 1; j <= i; j++) {
350 for (
unsigned j = 1; j < sz; j++) {
359 for (
unsigned i = 1; i <= h; i++)
362 const unsigned cap = w * h + 1;
363 for (
unsigned i = (w - 1) * h + 1; i <= w * h; i++)
372 const int type = rand() % 2;
391 for (
unsigned i = 3; i <= size; i++) {
392 for (
unsigned j = 1; j + 1 < i; j++) {
393 const unsigned th = (unsigned)rand() % (size * size);
394 if ((th <= w * w && (i < 5 || (i + 4 > h && j + 4 > h))) || th <= w)
402 fprintf(stderr,
"Warning: degenerate Moebius strip of %u vertices\n", w);
407 fprintf(stderr,
"Warning: degenerate Moebius strip of %u vertices\n", h);
412 for (
unsigned i = 0; i + 1 < w; i++) {
413 for (
unsigned j = 1; j < h; j++){
414 ef(j + i*h, j + (i+1)*h);
415 ef(j + i*h, j+1 + i*h);
419 for (
unsigned i = 1; i < h; i++){
420 ef (i + (w-1)*h, i+1 + (w-1)*h);
422 for (
unsigned i=1; i < w; i++) {
466 return tp->
p[tp->
root];
487 if (sz > 1) tp->
p[tp->
top] = tp->
top-1;
494 unsigned LS =
L + (J-1)*
M - 1;
495 for (
unsigned i =
L; i <= LS; i++) {
496 if ((i-
L)%
M == 0) tp->
p[i+
M] = LL;
497 else tp->
p[i+
M] = tp->
p[i] +
M;
504typedef LIST(
unsigned) int_stack_t;
506static void push(int_stack_t *sp,
unsigned j,
unsigned d) {
523static uint64_t
umul(uint64_t a, uint64_t b) {
526 fprintf(stderr,
"integer overflow in %" PRIu64
" * %" PRIu64
"\n", a, b);
533static uint64_t
uadd(uint64_t a, uint64_t b) {
536 fprintf(stderr,
"integer overflow in %" PRIu64
" + %" PRIu64
"\n", a, b);
543 uint64_t *
T =
gv_calloc(NN + 1,
sizeof(uint64_t));
548 for (
unsigned D = 1;
D <= NLAST;
D++) {
549 unsigned I = NLAST + 1;
550 const uint64_t TD =
umul(
T[
D],
D);
551 for (
unsigned J = 1; J <= NLAST; J++) {
558 T[NLAST] = SUM/(NLAST-1);
563static void genTree(
unsigned NN, uint64_t *
T, int_stack_t *stack,
572 const uint64_t v =
umul(
N - 1,
T[
N]);
579 const uint64_t TD =
umul(
D,
T[
D]);
584 if (
M <
D + 1)
break;
607 if (
treeTop(TREE) == NN)
return;
617 for (
unsigned i = 2; i <= tp->
top; i++)
633 tg->
sp = (int_stack_t){0};
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
static NORETURN void graphviz_exit(int status)
static gstack_t * push(gstack_t *s, Agraph_t *subg)
static void treePop(tree_t *tp)
static uint64_t * genCnt(unsigned NN)
void makeTriMesh(unsigned sz, edgefn ef)
static unsigned prevRoot(tree_t *tp)
void makeHypercube(unsigned dim, edgefn ef)
static void addTree(tree_t *tp, unsigned sz)
static unsigned treeSize(tree_t *tp)
void makeCircle(unsigned n, edgefn ef)
void makeTree(unsigned depth, unsigned nary, edgefn ef)
static void constructSierpinski(unsigned v1, unsigned v2, unsigned v3, unsigned depth, vtx_datas_t *graph)
static uint64_t umul(uint64_t a, uint64_t b)
multiply two 64-bit unsigned integers, exiting on overflow
static void writeTree(tree_t *tp, edgefn ef)
void makeWheel(unsigned n, edgefn ef)
void makeSquareGrid(unsigned dim1, unsigned dim2, int connect_corners, int partial, edgefn ef)
void makeBinaryTree(unsigned depth, edgefn ef)
static void constructTetrix(unsigned v1, unsigned v2, unsigned v3, unsigned v4, unsigned depth, vtx_datas_t *graph)
void makeComplete(unsigned n, edgefn ef)
void makeMobius(unsigned w, unsigned h, edgefn ef)
treegen_t * makeTreeGen(unsigned N)
void makeCompleteB(unsigned dim1, unsigned dim2, edgefn ef)
void makeBall(unsigned w, unsigned h, edgefn ef)
static void genTree(unsigned NN, uint64_t *T, int_stack_t *stack, tree_t *TREE)
void makePath(unsigned n, edgefn ef)
static unsigned treeRoot(tree_t *tp)
static void resetTree(tree_t *tp)
void makeTetrix(unsigned depth, edgefn ef)
void makeCylinder(unsigned dim1, unsigned dim2, edgefn ef)
void makeStar(unsigned n, edgefn ef)
static void treeDup(tree_t *tp, unsigned J)
void freeTreeGen(treegen_t *tg)
void makeTorus(unsigned dim1, unsigned dim2, edgefn ef)
void makeTwistedTorus(unsigned dim1, unsigned dim2, unsigned t1, unsigned t2, edgefn ef)
void makeRandomTree(treegen_t *tg, edgefn ef)
void makeRandom(unsigned h, unsigned w, edgefn ef)
static void freeTree(tree_t *tp)
void makeSierpinski(unsigned depth, edgefn ef)
static uint64_t uadd(uint64_t a, uint64_t b)
add two 64-bit unsigned integers, exiting on overflow
static tree_t * mkTree(unsigned sz)
static unsigned treeTop(tree_t *tp)
Agraph_t * graph(char *name)
static Agedge_t * top(edge_stack_t *sp)
type-generic dynamically expanding list
#define LIST_AT(list, index)
#define LIST_APPEND(list, item)
#define LIST_POP_BACK(list)
#define LIST_PUSH_BACK(list, item)
#define LIST_GET(list, index)
#define neighbor(t, i, edim, elist)
arithmetic overflow helpers
static bool u64mul_overflow(uint64_t a, uint64_t b, uint64_t *res)
static bool u64add_overflow(uint64_t a, uint64_t b, uint64_t *res)
uint64_t gv_random_u64(uint64_t bound)
void(* edgefn)(Agraph_t *, Agedge_t *, glCompColor)