diff options
author | alon@honor <none@none> | 2010-08-25 21:01:10 -0700 |
---|---|---|
committer | alon@honor <none@none> | 2010-08-25 21:01:10 -0700 |
commit | a9256705ada4ae335870cdb60ae7f9c8373038e3 (patch) | |
tree | 2c7aeabbdf38a9fea035d6680f8ad31b2a7e0d46 /tests/fannkuch.cpp | |
parent | f6d98e5d038ee80177b9414e5e34ddc05857627b (diff) |
the code
Diffstat (limited to 'tests/fannkuch.cpp')
-rw-r--r-- | tests/fannkuch.cpp | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/tests/fannkuch.cpp b/tests/fannkuch.cpp new file mode 100644 index 00000000..c2fcfaa2 --- /dev/null +++ b/tests/fannkuch.cpp @@ -0,0 +1,159 @@ +/* + * 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 <stdlib.h> +#include <stdio.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 ac, char **av) +{ + int n = ac > 1 ? atoi(av[1]) : 0; + + if (n < 1) { + printf("Wrong argument.\n"); + return 1; + } + printf("Pfannkuchen(%d) = %d.\n", n, fannkuch(n)); + return 0; +} + |