## Fannkuch

### Fannkuch Euphoria

```-- fannkuch.ex

-- original:
--  The Computer Language Benchmarks Game
-- http://shootout.alioth.debian.org/
-- contributed by Mike Pall

-- converted by Tom Ciplijauskas

--local function fannkuch(n)
function fannkuch( integer n )
integer temp
sequence p, q, s
integer sign = 1  --aka odd
integer maxflips = 0
atom sum = 0

p = repeat( 0, n )
for i=1 to n do
p[i] = i
end for

q = p
s = p

while 1 do      -->> Copy and flip.
integer q1 = p[1] 	-->> Cache 1st element.
if q1 != 1 then
q = p   -->> work on a copy
integer flips = 1
integer qq
while 1 do
qq = q[q1]
if qq = 1 then				-->> ... until 1st element is 1.
sum = sum + sign*flips
if flips > maxflips then maxflips = flips end if -->> New maximum?
exit
end if
q[q1] = q1
if q1 >= 4 then
integer i = 2
integer j = q1 - 1
loop do
temp = q[i]
q[i] = q[j]
q[j] = temp
i = i + 1
j = j - 1
until i >= j
end loop
end if
q1 = qq
flips = flips + 1
end while
end if

-- Permute.
if sign = 1 then
temp = p[2]
p[2] = p[1]
p[1] = temp
sign = -1
else
-->> Rotate 1<-2 and 1<-2<-3.
temp = p[2]
p[2] = p[3]
p[3] = temp
sign = 1
for i=3 to n do
integer sx = s[i]
if sx != 1 then
s[i] = sx-1
exit -- break
end if
if i = n then
return {sum, maxflips}
end if	-->> Out of permutations.
s[i] = i
-->> Rotate 1<-...<-i+1.
integer t = p[1]
for j=1 to i do
p[j] = p[j+1]
end for
p[i+1] = t
end for

end if
end while

end function

include std/get.e
include std/console.e
procedure main(sequence argv)
object N
if length(argv) >= 3 then
N = value(argv[3])
N = N[2]
else
N = 1
end if
display( N )
display( fannkuch(N) )
end procedure

main( command_line() )
```

### Fannkuch Python

```#    The Computer Language Benchmarks Game
#    http://shootout.alioth.debian.org/

#    contributed by Isaac Gouy
#    converted to Java by Oleg Mazurov
#    converted to Python by Buck Golemon
#    modified by Justin Peel

def fannkuch(n):
maxFlipsCount = 0
permSign = True
checksum = 0

perm1 = list(range(n))
count = perm1[:]
rxrange = range(2, n - 1)
#    print rxrange
nm = n - 1
while 1:
k = perm1[0]
#       print k
if k:
perm = perm1[:]
#           print perm
flipsCount = 1
kk = perm[k]
#          print kk
while kk:
#             print perm
#            print perm[:k+1]
#           print perm[k::-1]
perm[:k+1] = perm[k::-1]
#          print "----"
flipsCount += 1
k = kk
kk = perm[kk]
#                print "==done=="
if maxFlipsCount < flipsCount:
maxFlipsCount = flipsCount
checksum += flipsCount if permSign else -flipsCount

# Use incremental change to generate another permutation
if permSign:
perm1[0],perm1[1] = perm1[1],perm1[0]
permSign = False
else:
perm1[1],perm1[2] = perm1[2],perm1[1]
permSign = True
#          print "rxrange"
#         print rxrange
for r in rxrange:
#           print "r"
#          print r
if count[r]:
break
count[r] = r
perm0 = perm1[0]
perm1[:r+1] = perm1[1:r+2]
perm1[r+1] = perm0
else:
r = nm
if not count[r]:
print( checksum )
return maxFlipsCount
count[r] -= 1
from sys import argv
n = int(argv[1])

print(( "Pfannkuchen(%i) = %i" % (n, fannkuch(n)) ))

```

### Fannkuch Perl

```# The Computer Language Benchmarks Game
# http://shootout.alioth.debian.org/
# initial fannkuch port from C by Steve Clark
#   rewrite by Kalev Soikonen
#   modified by Kuang-che Wu
#   modified by David Golden
# updated for fannkuch-redux by Jonathan DePeri
#   permutations generated using Mike Pall's approach

use integer;

sub fannkuchredux {
my (\$n) = shift;
my (\$m, \$checksum, \$maxflips, \$flips, \$sign) = (\$n-1, 0, 0, 0, 1);
my (\$p, \$q, \$f, \$i, @count);

@count = (0..\$m);
\$p = pack "c*", @count;

do {
if (ord(substr(\$p,0))) {
\$q = \$p;
\$flips = 0;
while (\$f = ord(substr(\$q,0))) {
\$flips++;
substr(\$q, 0, \$f+1, reverse(substr(\$q,0,\$f+1)));
}
\$maxflips = \$flips if (\$flips > \$maxflips);
\$checksum += (\$sign * \$flips);
}

return if (\$n <= 1);
if (\$sign == 1) {
\$sign = -1;
substr \$p, 1, 0, (substr(\$p,0,1,""));
} else {
return if (\$n <= 2);
\$sign = 1;
substr \$p, 1, 0, (substr(\$p,2,1,""));
for \$i (2..\$m) {
if (\$count[\$i]) { \$count[\$i]--; last; }
return (\$checksum, \$maxflips) if (\$i == \$m);
\$count[\$i] = \$i;
substr \$p, \$i+1, 0, (substr(\$p,0,1,""));
}
}
} while (1);
}

for (shift) {
exit -1 if ((not defined \$_) || \$_ < 1);
my (\$checksum, \$maxflips) = fannkuchredux(\$_);
print "\$checksum\n";
print "Pfannkuchen(\$_) = \$maxflips\n";
}

```