123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include "Common.h"
- static void fannkuch(int n, int& sumOut, int& maxflipsOut)
- {
- int sum = 0;
- int maxflips = 0;
-
- /*int* p = (int*)alloca(sizeof(int)*n);
- int* q = (int*)alloca(sizeof(int)*n);
- int* s = (int*)alloca(sizeof(int)*n);*/
-
- int* p = new int[n];
- int* q = new int[n];
- int* s = new int[n];
- int sign = 1, m = n - 1;
- for (int i = 0; i < n; i++) { p[i] = i; q[i] = i; s[i] = i; }
- do
- {
- // Copy and flip.
- int q0 = p[0]; // Cache 0th element.
- if (q0 != 0)
- {
- for (int i = 1; i < n; i++) q[i] = p[i]; // Work on a copy.
- int flips = 1;
- do
- {
- int qq = q[q0];
- if (qq == 0)
- { // ... until 0th element is 0.
- sum += sign * flips;
- if (flips > maxflips) maxflips = flips; // New maximum?
- break;
- }
- q[q0] = q0;
- if (q0 >= 3)
- {
- int i = 1, j = q0 - 1, t;
- do { t = q[i]; q[i] = q[j]; q[j] = t; i++; j--; } while (i < j);
- }
- q0 = qq; flips++;
- } while (true);
- }
- // Permute.
- if (sign == 1)
- {
- int t = p[1]; p[1] = p[0]; p[0] = t; sign = -1; // Rotate 0<-1.
- }
- else
- {
- int t = p[1]; p[1] = p[2]; p[2] = t; sign = 1; // Rotate 0<-1 and 0<-1<-2.
- for (int i = 2; i < n; i++)
- {
- int sx = s[i];
- if (sx != 0) { s[i] = sx - 1; break; }
- if (i == m)
- {
- sumOut = sum;
- maxflipsOut = maxflips;
- return; // Out of permutations.
- }
- s[i] = i;
- // Rotate 0<-...<-i+1.
- t = p[0]; for (int j = 0; j <= i; j++) { p[j] = p[j + 1]; } p[i + 1] = t;
- }
- }
- } while (true);
- }
- void FannkuchRedux(int n)
- {
- int sum;
- int maxflips;
- fannkuch(n, sum, maxflips);
- Beefy::OutputDebugStrF("%d\nPfannkuchenC(%d) = %d\n", sum, n, maxflips);
- }
|