fannkuch.pp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. program fannkuch;
  2. { The Computer Language Shootout
  3. http://shootout.alioth.debian.org/
  4. contributed by Florian Klaempfl
  5. modified by Micha Nelissen
  6. modified by Vincent Snijders
  7. modified by Steve Fisher
  8. Compile with
  9. fpc -O3 fannkuch.pp
  10. }
  11. {$INLINE ON}
  12. {$OVERFLOWCHECKS OFF}
  13. {$RANGECHECKS OFF}
  14. type
  15. TIntegerArray = Array[0..99] of longint;
  16. var
  17. permu, permu_copy, count: TIntegerArray;
  18. r, n, answer: longint;
  19. procedure swap(var a, b: longint); inline;
  20. var tmp: longint;
  21. begin tmp := a; a := b; b := tmp end;
  22. procedure reverse( k: longint); inline;
  23. var
  24. pi, pj : pLongint;
  25. begin
  26. pi := @permu_copy[1];
  27. pj := @permu_copy[k-1];
  28. while pi<pj do
  29. begin
  30. swap(pi^, pj^);
  31. inc(pi);
  32. dec(pj);
  33. end;
  34. end;
  35. function countflips: longint; inline;
  36. var
  37. last: LongInt;
  38. tmp: LongInt;
  39. begin
  40. countflips := 0;
  41. last := permu_copy[0];
  42. repeat
  43. // Reverse part of the array.
  44. reverse(last);
  45. tmp := permu_copy[last];
  46. permu_copy[last] := last;
  47. last := tmp;
  48. inc(countflips);
  49. until last = 0;
  50. end;
  51. function NextPermutation: boolean;
  52. var
  53. tmp: LongInt;
  54. i : longint;
  55. begin
  56. NextPermutation := true;
  57. repeat
  58. if r = n then
  59. begin
  60. NextPermutation := false;
  61. break;
  62. end;
  63. tmp := permu[0];
  64. for i := 1 to r do
  65. permu[i-1] := permu[i];
  66. permu[r] := tmp;
  67. dec(count[r]);
  68. if count[r] > 0 then
  69. break;
  70. inc(r);
  71. until false;
  72. end;
  73. function fannkuch: longint;
  74. var
  75. print30, m, i, flips: longint;
  76. begin
  77. print30 := 0;
  78. fannkuch := 0;
  79. m := n - 1;
  80. // Initial permutation.
  81. for i := 0 to m do permu[i] := i;
  82. r := n;
  83. repeat
  84. if print30 < 30 then
  85. begin
  86. for i := 0 to m do
  87. write(permu[i] + 1);
  88. writeln;
  89. inc(print30);
  90. end;
  91. while r <> 1 do
  92. begin
  93. count[r-1] := r;
  94. dec(r);
  95. end;
  96. if (permu[0]<>0) and (permu[m]<>m) then
  97. begin
  98. move(permu[0], permu_copy[0], sizeof(longint)*n);
  99. flips := countflips;
  100. if flips > fannkuch then
  101. fannkuch := flips;
  102. end;
  103. until not NextPermutation;
  104. end;
  105. begin
  106. n := 7;
  107. if paramCount() = 1 then
  108. Val(ParamStr(1), n);
  109. answer := fannkuch;
  110. writeln('Pfannkuchen(', n, ') = ', answer);
  111. end.