#include "defs.h"
#define PSP 60000
#define MP 200
#define NPT 8000
#define MB 50
char opt[40], sysstring[40];
short mp = MP, mpt = NPT, mb = MB, npt, perm[PSP], cp[100], *pptr[MP],
orb[NPT + 1], orno[NPT + 1], pno[MP], base[MB];
int psp = PSP;
FILE *ip, *op;
int main(void)
{
short i, j, m, n, y, np, nb, mxp, ord, im, len, *p, *q;
int quot;
int chct;
char nt, f, id, eq, fault, flnm[80];
reenter:
printf("Do you wish to read permutations from a file (y/n)? ");
if (getchar() == 'y') {
f = 1;
snl();
printf("Input filename: ");
scanf("%s", flnm);
snl();
if ((ip = fopen(flnm, "r")) == 0) {
fprintf(stderr, "Cannot open %s.\n", flnm);
goto reenter;
}
fscanf(ip, "%hd%hd%hd%hd", &npt, &np, &nb, &m);
seeknln();
if (nb != 0) {
if (nb >= mb) {
fprintf(stderr, "Too many base points. Increase MB.\n");
return (-1);
}
for (i = 1; i <= nb; i++)
fscanf(ip, "%hd", base + i);
seeknln();
}
if (m != 0)
seeknln();
}
else {
f = 0;
snl();
printf("Input npt: ");
scanf("%hd", &npt);
snl();
nb = 0;
}
if (npt > mpt) {
fprintf(stderr, "npt too big. Increase NPT.\n");
exit(1);
}
quot = psp / npt;
if (quot > mp)
mxp = mp;
else
mxp = quot;
printf("Perm nos 1 - %d can be read. Perm no 0 is always the identity\n",
mxp - 1);
for (i = 0; i < mxp; i++) {
pptr[i] = perm - 1 + npt * i;
pno[i] = 0;
}
p = pptr[0];
for (i = 1; i <= npt; i++)
p[i] = i;
pno[0] = 1;
if (f) {
if (np >= mxp) {
fprintf(stderr, "Not enough perm space to read perms from file.");
fprintf(stderr, " Increase PSP (or MP).\n");
exit(1);
}
for (i = 1; i <= np; i++) {
if (readperm(pptr[i]) == 2) {
fprintf(stderr, "Perm no %i is not a permutation.\n");
exit(1);
}
pno[i] = 1;
seeknln();
}
fclose(ip);
}
while (1) {
printf("Choose option. Print 'l' for list.\n");
scanf("%s", opt);
if (strcmp(opt, "l") == 0) {
snl();
printf("rp n = read perm no n.\n");
printf("pp n = print perm no n.\n");
printf("ppc n = print perm no n in cycles.\n");
printf("inv m n = calc inverse p[n] of p[m].\n");
printf("pr n l i(1)...i(l) = calc prod p[n] of p[i(1)]...p[i(l)].\n");
printf("im m x = print image of point x under p[m].\n");
printf("fp n = print fixed pts of p[n].\n");
printf("fpn l i(1)...i(l) = print common fixed pts of "
"p[i(1)],...,p[i(l)].\n");
printf("cyc n x = print cycle of point x under p[n].\n");
printf("ord n = print order of p[n].\n");
printf("orb l i(1)...i(l) = print orbits of p[i(1)]...p[i(l)].\n");
printf("rb = read in a base for the group.\n");
printf("op filename = output some perms to 'filename'.\n");
printf("opord filename = output some perms to 'filename' and\n");
printf(
" compute order of group they generate.\n");
printf(" (Only works if base known for G!).\n");
printf(
"rf n filename = read in additional perms from filename\n");
printf(" starting at perm. no. n.\n");
printf("q = quit.\n");
}
else if (strcmp(opt, "rp") == 0) {
scanf("%hd", &n);
snl();
if (n <= 0 || n >= mxp)
fprintf(stderr, "Invalid perm.no %d.\n", n);
else {
while (rp(pptr[n]) == 2) {
fprintf(stderr, "That is not a permutation. Try again!\n");
snl();
}
pno[n] = 1;
}
}
else if (strcmp(opt, "pp") == 0) {
scanf("%hd", &n);
snl();
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
continue;
}
p = pptr[n];
for (i = 1; i <= npt; i++)
printf("%4d", p[i]);
printf("\n");
}
else if (strcmp(opt, "ppc") == 0) {
scanf("%hd", &n);
snl();
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
continue;
}
for (i = 1; i <= npt; i++)
orb[i] = 1;
p = pptr[n];
id = 1;
chct = 0;
for (m = 1; m <= npt; m++)
if (orb[m]) {
if ((im = p[m]) != m) {
id = 0;
orb[im] = 0;
printf("(%d,%d", m, im);
chct += (num_digits(m) + num_digits(im) + 2);
while ((im = p[im]) != m) {
if (chct >= 75) {
printf(",\n%d", im);
chct = num_digits(im);
}
else {
printf(",%d", im);
chct += (1 + num_digits(im));
}
orb[im] = 0;
}
printf(")");
chct++;
if (chct >= 72) {
printf("\n");
chct = 0;
}
}
}
if (id)
printf("Perm no %d is the identity.\n", n);
else
printf("\n");
}
else if (strcmp(opt, "inv") == 0) {
scanf("%hd%hd", &m, &n);
snl();
if (m < 0 || m >= mxp || pno[m] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", m);
continue;
}
if (n <= 0 || n >= mxp) {
fprintf(stderr, "Invalid perm. no. %d.\n", n);
continue;
}
invert(pptr[m], pptr[n]);
pno[n] = 1;
}
else if (strcmp(opt, "pr") == 0) {
scanf("%hd%hd", &m, cp);
if (m <= 0 || m >= mxp) {
fprintf(stderr, "Invalid perm no. %d\n", m);
snl();
continue;
}
fault = 0;
for (i = 1; i <= *cp; i++) {
scanf("%hd", cp + i);
n = *(cp + i);
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
fault = 1;
snl();
break;
}
}
if (fault)
continue;
snl();
p = pptr[m];
for (i = 1; i <= npt; i++)
p[i] = image(i);
pno[m] = 1;
}
else if (strcmp(opt, "im") == 0) {
scanf("%hd%hd", &n, &i);
snl();
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
continue;
}
if (i <= 0 || i > npt) {
fprintf(stderr, "Inappropriate point %d.\n", i);
continue;
}
printf("%d\n", pptr[n][i]);
}
else if (strcmp(opt, "fp") == 0) {
scanf("%hd", &n);
snl();
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
continue;
}
p = pptr[n];
nt = 1;
for (i = 1; i <= npt; i++)
if (p[i] == i) {
nt = 0;
printf("%4d", i);
}
if (nt)
printf("No fixed points.\n");
else
printf("\n");
}
else if (strcmp(opt, "fpn") == 0) {
scanf("%hd", cp);
fault = 0;
for (i = 1; i <= *cp; i++) {
scanf("%hd", cp + i);
n = *(cp + i);
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
fault = 1;
snl();
break;
}
}
if (fault)
continue;
snl();
nt = 1;
for (n = 1; n <= npt; n++) {
f = 1;
for (i = 1; i <= *cp; i++)
if (pptr[cp[i]][n] != n) {
f = 0;
break;
}
if (f) {
nt = 0;
printf("%4d", n);
}
}
if (nt)
printf("No fixed points.\n");
else
printf("\n");
}
else if (strcmp(opt, "cyc") == 0) {
scanf("%hd%hd", &n, &i);
snl();
if (i <= 0 || i > npt) {
fprintf(stderr, "Inappropriate point %d.\n", i);
continue;
}
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
continue;
}
p = pptr[n];
if ((im = p[i]) == i)
printf("%d is fixed under p[%d].\n", i, n);
else {
printf("(%d,%d", i, im);
while ((im = p[im]) != i)
printf(",%d", im);
printf(")\n");
}
}
else if (strcmp(opt, "ord") == 0) {
scanf("%hd", &n);
snl();
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
continue;
}
p = pptr[n];
id = 1;
for (i = 1; i <= npt; i++)
orb[i] = 1;
ord = 1;
for (m = 1; m <= npt; m++)
if (orb[m]) {
if ((im = p[m]) != m) {
id = 0;
orb[im] = 0;
len = 2;
while ((im = p[im]) != m) {
orb[im] = 0;
len++;
}
ord = lcm(ord, len);
}
}
if (id)
printf("Perm no %d is the identity.\n", n);
else
printf("%d\n", ord);
}
else if (strcmp(opt, "orb") == 0) {
scanf("%hd", cp);
fault = 0;
for (i = 1; i <= *cp; i++) {
scanf("%hd", cp + i);
n = *(cp + i);
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
fault = 1;
snl();
break;
}
}
if (fault)
continue;
snl();
allorbs();
}
else if (strcmp(opt, "eq") == 0) {
scanf("%hd%hd", &m, &n);
snl();
if (n < 0 || n >= mxp || pno[n] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", n);
continue;
}
if (m < 0 || m >= mxp || pno[m] == 0) {
fprintf(stderr, "Perm no %d is not defined.\n", m);
continue;
}
p = pptr[m];
q = pptr[n];
eq = 1;
for (i = 1; i <= npt; i++)
if (p[i] != q[i]) {
eq = 0;
break;
}
if (eq)
printf("Permutations are equal.\n");
else
printf("Permutations are not equal on point %d.\n", i);
}
else if (strcmp(opt, "rb") == 0) {
snl();
printf("Input base points, preceded by their number.\n");
scanf("%hd", &nb);
if (nb >= mb) {
fprintf(stderr, "Too many base points. Increase MB.\n");
return (-1);
}
for (i = 1; i <= nb; i++)
scanf("%hd", base + i);
snl();
}
else if ((y = strcmp(opt, "opord")) == 0 || strcmp(opt, "op") == 0) {
if (y == 0 && nb == 0) {
fprintf(stderr, "Order can only be computed when base is known.\n");
continue;
}
scanf("%s", flnm);
snl();
op = fopen(flnm, "w");
printf("Input perm nos to be saved, preceded by their number.\n");
scanf("%hd", &n);
fprintf(op, "%3d %4d%4d%4d\n", npt, n, nb, 0);
if (nb != 0)
if (npt >= 10000) {
for (i = 1; i <= nb; i++)
fprintf(op, "%6d", base[i]);
fprintf(op, "\n");
}
else if (npt >= 1000) {
for (i = 1; i <= nb; i++)
fprintf(op, "%5d", base[i]);
fprintf(op, "\n");
}
else {
for (i = 1; i <= nb; i++)
fprintf(op, "%4d", base[i]);
fprintf(op, "\n");
}
f = 0;
for (i = 1; i <= n; i++) {
scanf("%hd", &m);
if (m < 0 || m >= mxp || pno[m] == 0) {
printf("Perm no %d is not defined.\n", m);
fclose(op);
snl();
unlink(flnm);
f = 1;
break;
}
printvec(pptr[m], 0);
}
if (f)
continue;
snl();
fclose(op);
if (y == 0) {
sprintf(sysstring, "cp %s optxxx.ip", flnm);
system(sysstring);
system("gprun -b optxxx ip ip");
unlink("optxxx.ip");
}
}
else if (strcmp(opt, "rf") == 0) {
scanf("%hd", &n);
scanf("%s", flnm);
snl();
if ((ip = fopen(flnm, "r")) == 0) {
fprintf(stderr, "Cannot open %s.\n", flnm);
continue;
}
fscanf(ip, "%hd%hd%hd%hd", &i, &np, &j, &m);
seeknln();
if (i != npt) {
fprintf(stderr, "npt does not agree.\n");
fclose(ip);
continue;
}
if (j != 0)
seeknln();
if (m != 0)
seeknln();
if (n <= 0 || np + n - 1 >= mxp) {
fprintf(stderr, "Not enough perm space to read perms from file.");
fclose(ip);
continue;
}
for (i = 1; i <= np; i++) {
if (readperm(pptr[i + n - 1]) == 2) {
fprintf(stderr, "Perm no %i is not a permutation.\n");
pno[i + n - 1] = 0;
break;
}
pno[i + n - 1] = 1;
seeknln();
}
fclose(ip);
}
else if (strcmp(opt, "q") == 0) {
snl();
break;
}
else {
printf("Invalid option.\n");
snl();
}
}
exit(0);
}
int snl(void)
{
while (getchar() != '\n')
;
}
int lcm(int x, int y)
{
short a, b, c;
a = x;
b = y;
while ((c = a % b) != 0) {
a = b;
b = c;
}
return (x * y / b);
}
int rp(short * ptr)
{
short i, j;
for (i = 1; i <= npt; i++)
orb[i] = 0;
for (i = 1; i <= npt; i++) {
scanf("%hd", ptr + i);
j = ptr[i];
if (j <= 0 || j > npt || orb[j])
return (2);
orb[j] = 1;
}
return (0);
}
int allorbs(void)
{
short orct, lo, u, v, w, x, y, z;
for (u = 1; u <= npt; u++)
orno[u] = 0;
orct = 0;
for (u = 1; u <= npt; u++)
if (orno[u] == 0) {
orct++;
orno[u] = orct;
lo = 1;
orb[1] = u;
for (x = 1; x <= lo; x++) {
z = orb[x];
for (y = 1; y <= *cp; y++) {
w = cp[y];
v = pptr[w][z];
if (orno[v] == 0) {
lo++;
orb[lo] = v;
orno[v] = orct;
}
}
}
printf("Orbit number %3d, length %3d:\n", orct, lo);
for (x = 1; x <= lo; x++)
printf("%4d", orb[x]);
printf("\n");
}
return (0);
}
int num_digits(int n)
{
if (n < 10)
return (1);
if (n < 100)
return (2);
if (n < 1000)
return (3);
if (n < 10000)
return (4);
if (n < 100000)
return (5);
return (6);
}
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|