/* * polyaboloes - make a list of polyaboloes of a given order. * $Id: polyaboloes.c,v 1.6 2020/10/23 19:56:45 gls Exp $ * * polyaboloes [-x] * * -x Generate polyfetts, vertex-connected polyaboloes. * * Writes to polyaboloes. or polyfetts.. * * The input and output files have one polyabolo on each line. * A polyabolo is represented as a series of integers, of which * the first three represent the first cell, the second three * the second cell, and so on. The three values are x, y * (measured downward), and one of {3, 5, 10, 12, 15}. * 1 is the bottom sector, 2 the right, 4 the left, and 8 the top. */ #include #include #include #include #include #include typedef struct cell { int x, y, s; } CELL; static void usage(); static void add(int sector); static void canonize(); static int vacant(int x, int y); static int lexbefore(); static int cellcompare(const void *a, const void *b); static void show(); int ncells, xnew, ynew, xflag; int nwcells, nbcells; CELL *cells, *wcells, *bcells; static FILE *In, *Out; static void usage() { fprintf(stderr, "usage: polyaboloes [-x] \n" "-x\tGenerate polyfetts instead of polyaboloes.\n"); exit(1); } static int reflbits[16] = { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 }; static int rotbits[16] = { 0, 2, 8, 10, 1, 3, 9, 11, 4, 6, 12, 14, 5, 7, 13, 15 }; int main(int argc, char **argv) { int n, k, c, x, y, v, opt; char outbuf[128], inbuf[128], *cur; struct stat outstat, instat; while (-1 != (opt = getopt(argc, argv, "x?"))) switch(opt) { case 'x': xflag = 1; break; default: usage(); } argc -= optind; argv += optind; if (argc != 1) usage(); if (!isdigit(**argv)) usage(); n = atoi(*argv); if (n==0) { fprintf(stderr, "polyaboloes: n must be positive.\n"); exit(1); } if (n>99) { fprintf(stderr, "polyaboloes: n must be less than 100.\n"); exit(1); } sprintf(outbuf, xflag? "polyfetts.%d": "polyaboloes.%d", n); if (0 == stat(outbuf, &outstat) && outstat.st_size > 0) { fprintf(stderr, "polyaboloes: %s is not empty.\n", outbuf); exit(1); } if (n == 1) { Out = fopen(outbuf, "w"); if (!Out) { fprintf(stderr, "polyaboloes: cannot write to %s.\n", outbuf); exit(1); } fprintf(Out, "0 0 3\n"); exit(0); } sprintf(inbuf, xflag? "polyfetts.%d": "polyaboloes.%d", n - 1); if (0 != stat(inbuf, &instat) || instat.st_size == 0) { fprintf(stderr, "polyaboloes: %s is missing or empty.\n", inbuf); exit(1); } In = fopen(inbuf, "r"); if (!In) { fprintf(stderr, "polyaboloes: cannot write to %s.\n", outbuf); exit(1); } sprintf(outbuf, "sort -u --compress-program=gzip >%s.%d", xflag? "polyfetts": "polyaboloes", n); Out = popen(outbuf, "w"); if (!Out) { fprintf(stderr, "polyaboloes: cannot sort to %s.\n", outbuf+33); exit(1); } /* * Allocate arrays of cells. */ cells = calloc(n, sizeof(CELL)); wcells = calloc(n, sizeof(CELL)); /* working */ bcells = calloc(n, sizeof(CELL)); /* canonized */ while (fgets(inbuf, 128, In)) { /* * Process an (n-1)-abolo. */ char *nl = strchr(inbuf, '\n'); if (!nl) { fprintf(stderr, "polyaboloes: incomplete input line.\n"); exit(1); } *nl = '\0'; /* fprintf(stderr, "read %s\n", inbuf); */ ncells = 0; cur = inbuf; for (k=0; k 0) return 0; if (d < 0) return 1; } return 0; /* identical */ } static int cellcompare(const void *a, const void *b) { int d; const CELL *ca, *cb; ca = (const CELL *)a; cb = (const CELL *)b; d = ca->y - cb->y; if (d) return d; d = ca->x - cb->x; if (d) return d; d = ca->s - cb->s; return d; } static int vacant(int x, int y) { int c; for (c=0; c