\ The Computer Language Shootout
\ http://shootout.alioth.debian.org

\ Contributed by Ian Osgood and Bernd Paysan

\ read NUM from last command line argument
0. argc @ 1- arg >number 2drop drop constant NUM

Variable perms
Variable flips#

Create a num allot
Create b num allot

\ Athlon64 padding
$200 allot

: .pan ( a -- ) NUM 0 do dup c@ 1 u.r 1+ loop drop cr ;

: flip ( n -- )
  dup a +  swap 2/ a +  a do
    1-  i c@ over c@  i c! over c!
  loop drop ;

: flips ( -- n )
  0 begin a c@ 1 > while 1+  a c@ flip repeat ;

: 0-fannkuch ( n -- n' )
    b a num move perms @ 30 < IF  a .pan  1 perms +!  THEN
    flips max ;

: n-fannkuch ( n -- )
    b b 1+ num 1- move dup b c!
    dup num = IF
	flips# @ b rot 1- bounds ?DO
	    0-fannkuch  I c@ I 1+ c@ I c! I 1+ c!  LOOP
	0-fannkuch flips# ! EXIT  THEN
    b over 1- bounds ?DO
	dup 1+ recurse  I c@ I 1+ c@ I c! I 1+ c!  LOOP
    1+ recurse ;

: fannkuch ( -- max-flips )
    1 n-fannkuch flips# @ ;

fannkuch ." Pfannkuchen(" NUM 1 u.r ." ) = " 1 u.r space cr bye
