import os import strutils proc fannkuch (n: int): int = var count: seq[int] maxFlips = 0 m = n-1 r = n check = 0 perm1: seq[int] perm: seq[int] newSeq (count, n+1) newSeq (perm1, n) newSeq (perm, n) for i in 0 .. n-1: count[i] = i+1 perm1[i] = i perm[i] = i count[n] = n+1 while True: if check < 30: for i in items (perm1): write (stdout, $(i+1)) echo ("") inc (check) while r != 1: count[r-1] = r dec (r) if perm1[0] != 0 and perm1[m] != m: # perm = perm1 # The above line is between 3 and 4 times slower than the loop below! for i in 0 .. n-1: perm[i] = perm1[i] var flipsCount = 0 var k = perm[0] while k != 0: for i in 0 .. (k div 2): swap (perm[i], perm[k-i]) inc (flipsCount) k = perm[0] if flipsCount > maxFlips: maxFlips = flipsCount block makePerm: while r != n: var tmp = perm1[0] # # perm1.delete (0) # # perm1.insert (tmp, r) # # The above is about twice as slow as the following: # moveMem (addr (perm1[0]), addr (perm1[1]), r * sizeof (int)) # The call to moveMem is about 50% slower than the loop below! for i in 0 .. r-1: perm1[i] = perm1[i+1] perm1[r] = tmp dec (count[r]) if count[r] > 0: break makePerm inc (r) return maxFlips var n = 10 echo ("Pfannkuchen(" & $n & ") = " & $fannkuch (n))