fannkuchredux.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include "Common.h"
  5. static void fannkuch(int n, int& sumOut, int& maxflipsOut)
  6. {
  7. int sum = 0;
  8. int maxflips = 0;
  9. /*int* p = (int*)alloca(sizeof(int)*n);
  10. int* q = (int*)alloca(sizeof(int)*n);
  11. int* s = (int*)alloca(sizeof(int)*n);*/
  12. int* p = new int[n];
  13. int* q = new int[n];
  14. int* s = new int[n];
  15. int sign = 1, m = n - 1;
  16. for (int i = 0; i < n; i++) { p[i] = i; q[i] = i; s[i] = i; }
  17. do
  18. {
  19. // Copy and flip.
  20. int q0 = p[0]; // Cache 0th element.
  21. if (q0 != 0)
  22. {
  23. for (int i = 1; i < n; i++) q[i] = p[i]; // Work on a copy.
  24. int flips = 1;
  25. do
  26. {
  27. int qq = q[q0];
  28. if (qq == 0)
  29. { // ... until 0th element is 0.
  30. sum += sign * flips;
  31. if (flips > maxflips) maxflips = flips; // New maximum?
  32. break;
  33. }
  34. q[q0] = q0;
  35. if (q0 >= 3)
  36. {
  37. int i = 1, j = q0 - 1, t;
  38. do { t = q[i]; q[i] = q[j]; q[j] = t; i++; j--; } while (i < j);
  39. }
  40. q0 = qq; flips++;
  41. } while (true);
  42. }
  43. // Permute.
  44. if (sign == 1)
  45. {
  46. int t = p[1]; p[1] = p[0]; p[0] = t; sign = -1; // Rotate 0<-1.
  47. }
  48. else
  49. {
  50. int t = p[1]; p[1] = p[2]; p[2] = t; sign = 1; // Rotate 0<-1 and 0<-1<-2.
  51. for (int i = 2; i < n; i++)
  52. {
  53. int sx = s[i];
  54. if (sx != 0) { s[i] = sx - 1; break; }
  55. if (i == m)
  56. {
  57. sumOut = sum;
  58. maxflipsOut = maxflips;
  59. return; // Out of permutations.
  60. }
  61. s[i] = i;
  62. // Rotate 0<-...<-i+1.
  63. t = p[0]; for (int j = 0; j <= i; j++) { p[j] = p[j + 1]; } p[i + 1] = t;
  64. }
  65. }
  66. } while (true);
  67. }
  68. void FannkuchRedux(int n)
  69. {
  70. int sum;
  71. int maxflips;
  72. fannkuch(n, sum, maxflips);
  73. Beefy::OutputDebugStrF("%d\nPfannkuchenC(%d) = %d\n", sum, n, maxflips);
  74. }