FannKuch
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"; }