| /* | |
| * The Computer Language Benchmarks Game | |
| * http://shootout.alioth.debian.org/ | |
| * | |
| * Contributed by Eckehard Berns | |
| * Based on code by Heiner Marxen | |
| * and the ATS version by Hongwei Xi | |
| * | |
| * Modified for emscripten by azakai | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| struct worker_args { | |
| int i, n; | |
| struct worker_args* next; | |
| }; | |
| int fannkuch_worker(void* _arg) { | |
| struct worker_args* args = (worker_args*)_arg; | |
| int *perm1, *count, *perm; | |
| int maxflips, flips, i, n, r, j, k, tmp; | |
| maxflips = 0; | |
| n = args->n; | |
| perm1 = (int*)malloc(n * sizeof(int)); | |
| perm = (int*)malloc(n * sizeof(int)); | |
| count = (int*)malloc(n * sizeof(int)); | |
| for (i = 0; i < n; i++) | |
| perm1[i] = i; | |
| perm1[args->i] = n - 1; | |
| perm1[n - 1] = args->i; | |
| r = n; | |
| for (;;) { | |
| for (; r > 1; r--) | |
| count[r - 1] = r; | |
| if (perm1[0] != 0 && perm1[n - 1] != n - 1) { | |
| for (i = 0; i < n; i++) | |
| perm[i] = perm1[i]; | |
| flips = 0; | |
| k = perm[0]; | |
| do { | |
| for (i = 1, j = k - 1; i < j; i++, j--) { | |
| tmp = perm[i]; | |
| perm[i] = perm[j]; | |
| perm[j] = tmp; | |
| } | |
| flips++; | |
| tmp = perm[k]; | |
| perm[k] = k; | |
| k = tmp; | |
| } while (k); | |
| if (maxflips < flips) | |
| maxflips = flips; | |
| } | |
| for (;;) { | |
| if (r >= n - 1) { | |
| free(perm1); | |
| free(perm); | |
| free(count); | |
| return maxflips; | |
| } | |
| { | |
| int p0 = perm1[0]; | |
| for (i = 0; i < r; i++) | |
| perm1[i] = perm1[i + 1]; | |
| perm1[i] = p0; | |
| } | |
| if (--count[r] > 0) | |
| break; | |
| r++; | |
| } | |
| } | |
| } | |
| static int fannkuch(int n) { | |
| struct worker_args *args, *targs; | |
| int showmax = 30; | |
| int *perm1, *count, i, r, maxflips, flips; | |
| args = NULL; | |
| for (i = 0; i < n - 1; i++) { | |
| targs = (worker_args*)malloc(sizeof(struct worker_args)); | |
| targs->i = i; | |
| targs->n = n; | |
| targs->next = args; | |
| args = targs; | |
| } | |
| perm1 = (int*)malloc(n * sizeof(int)); | |
| count = (int*)malloc(n * sizeof(int)); | |
| for (i = 0; i < n; i++) | |
| perm1[i] = i; | |
| r = n; | |
| for (;;) { | |
| if (showmax) { | |
| for (i = 0; i < n; i++) | |
| printf("%d", perm1[i] + 1); | |
| printf("\n"); | |
| showmax--; | |
| } else | |
| goto cleanup; | |
| for (; r > 1; r--) | |
| count[r - 1] = r; | |
| for (;;) { | |
| if (r == n) | |
| goto cleanup; | |
| { | |
| int p0 = perm1[0]; | |
| for (i = 0; i < r; i++) | |
| perm1[i] = perm1[i + 1]; | |
| perm1[i] = p0; | |
| } | |
| if (--count[r] > 0) | |
| break; | |
| r++; | |
| } | |
| } | |
| cleanup: | |
| free(perm1); | |
| free(count); | |
| maxflips = 0; | |
| while (args != NULL) { | |
| flips = (int)fannkuch_worker(args); | |
| if (maxflips < flips) | |
| maxflips = flips; | |
| targs = args; | |
| args = args->next; | |
| free(targs); | |
| } | |
| return maxflips; | |
| } | |
| int main(int argc, char** argv) { | |
| int n = argc > 1 ? atoi(argv[1]) : 0; | |
| if (n < 1) { | |
| printf("Wrong argument.\n"); | |
| return 1; | |
| } | |
| printf("Pfannkuchen(%d) = %d.\n", n, fannkuch(n)); | |
| return 0; | |
| } |