Topswops: Difference between revisions

15,347 bytes added ,  3 months ago
m
(Added 11l)
m (→‎{{header|Wren}}: Minor tidy)
 
(9 intermediate revisions by 8 users not shown)
Line 42:
{{trans|Python:_Faster_Version}}
 
<langsyntaxhighlight lang="11l">V best = [0] * 16
 
F try_swaps(&deck, f, =s, d, n)
Line 83:
 
L(i) 1..12
print(‘#2: #.’.format(i, topswops(i)))</langsyntaxhighlight>
 
{{out}}
Line 103:
=={{header|360 Assembly}}==
The program uses two ASSIST macro (XDECO,XPRNT) to keep the code as short as possible.
<langsyntaxhighlight lang="360asm">* Topswops optimized 12/07/2016
TOPSWOPS CSECT
USING TOPSWOPS,R13 base register
Line 223:
BR R14 ---------------}-----------------------------------
YREGS
END TOPSWOPS</langsyntaxhighlight>
{{out}}
<pre>
Line 241:
This is a straightforward approach that counts the number of swaps for each permutation. To generate all permutations over 1 .. N, for each of N in 1 .. 10, the package Generic_Perm from the Permutations task is used [[http://rosettacode.org/wiki/Permutations#The_generic_package_Generic_Perm]].
 
<langsyntaxhighlight Adalang="ada">with Ada.Integer_Text_IO, Generic_Perm;
 
procedure Topswaps is
Line 279:
Ada.Integer_Text_IO.Put(Item => Topswaps(I), Width => 3);
end loop;
end Topswaps;</langsyntaxhighlight>
 
{{out}}<pre> 0 1 2 4 7 10 16 22 30 38</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">Topswops(Obj, n){
R := []
for i, val in obj{
Line 295:
R[A_Index]:= A_LoopField
return R
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">Cards := [2, 4, 1, 3]
Res := Print(Cards)
while (Cards[1]<>1)
Line 309:
Res .= (A_Index=1?"":"`t") val
return Trim(Res,"`n")
}</langsyntaxhighlight>
Outputs:<pre>2 4 1 3
4 2 1 3
Line 318:
=={{header|C}}==
An algorithm that doesn't go through all permutations, per Knuth tAoCP 7.2.1.2 exercise 107 (possible bad implementation on my part notwithstanding):
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
 
Line 362:
 
return 0;
}</langsyntaxhighlight>
The code contains critical small loops, which can be manually unrolled for those with OCD. POSIX thread support is useful if you got more than one CPUs.
<langsyntaxhighlight lang="c">#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
Line 479:
return 0;
}</langsyntaxhighlight>
 
 
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
 
public class Topswops {
static readonly int maxBest = 32;
static int[] best;
 
private static void TrySwaps(int[] deck, int f, int d, int n) {
if (d > best[n])
best[n] = d;
 
for (int i = n - 1; i >= 0; i--) {
if (deck[i] == -1 || deck[i] == i)
break;
if (d + best[i] <= best[n])
return;
}
 
int[] deck2 = (int[])deck.Clone();
for (int i = 1; i < n; i++) {
int k = 1 << i;
if (deck2[i] == -1) {
if ((f & k) != 0)
continue;
} else if (deck2[i] != i)
continue;
 
deck2[0] = i;
for (int j = i - 1; j >= 0; j--)
deck2[i - j] = deck[j]; // Reverse copy.
TrySwaps(deck2, f | k, d + 1, n);
}
}
 
static int topswops(int n) {
if(n <= 0 || n >= maxBest) throw new ArgumentOutOfRangeException(nameof(n), "n must be greater than 0 and less than maxBest.");
best[n] = 0;
int[] deck0 = new int[n + 1];
for (int i = 1; i < n; i++)
deck0[i] = -1;
TrySwaps(deck0, 1, 0, n);
return best[n];
}
 
public static void Main(string[] args) {
best = new int[maxBest];
for (int i = 1; i < 11; i++)
Console.WriteLine(i + ": " + topswops(i));
}
}
</syntaxhighlight>
{{out}}
<pre>
1: 0
2: 1
3: 2
4: 4
5: 7
6: 10
7: 16
8: 22
9: 30
10: 38
 
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <vector>
Line 507 ⟶ 576:
}
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 525 ⟶ 594:
http://rosettacode.org/wiki/Permutations#Faster_Lazy_Version
{{trans|Haskell}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, permutations2;
 
int topswops(in int n) pure @safe {
Line 539 ⟶ 608:
foreach (immutable i; 1 .. 11)
writeln(i, ": ", i.topswops);
}</langsyntaxhighlight>
{{out}}
<pre>1: 0
Line 554 ⟶ 623:
===D: Faster Version===
{{trans|C}}
<langsyntaxhighlight lang="d">import std.stdio, std.typecons;
 
__gshared uint[32] best;
Line 605 ⟶ 674:
foreach (immutable i; staticIota!(1, 14))
writefln("%2d: %d", i, topswops!i());
}</langsyntaxhighlight>
{{out}}
<pre> 1: 0
Line 623 ⟶ 692:
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
<lang Eiffel>
class
TOPSWOPS
Line 735 ⟶ 804:
 
end
</syntaxhighlight>
</lang>
Test:
<syntaxhighlight lang="eiffel">
<lang Eiffel>
class
APPLICATION
Line 759 ⟶ 828:
 
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 776 ⟶ 845:
=={{header|Elixir}}==
{{trans|Erlang}}
<langsyntaxhighlight lang="elixir">defmodule Topswops do
def get_1_first( [1 | _t] ), do: 0
def get_1_first( list ), do: 1 + get_1_first( swap(list) )
Line 799 ⟶ 868:
end
 
Topswops.task</langsyntaxhighlight>
 
{{out}}
Line 818 ⟶ 887:
=={{header|Erlang}}==
This code is using the [[Permutations | permutation]] code by someone else. Thank you.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( topswops ).
 
Line 840 ⟶ 909:
 
get_1_first_many( N_permutations ) -> [get_1_first(X) || X <- N_permutations].
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 858 ⟶ 927:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: formatting kernel math math.combinatorics math.order
math.ranges sequences ;
FROM: sequences.private => exchange-unsafe ;
Line 883 ⟶ 952:
10 [1,b] [ dup topswops "%2d: %2d\n" printf ] each ;
 
MAIN: main</langsyntaxhighlight>
{{out}}
<pre>
Line 899 ⟶ 968:
 
=={{header|Fortran}}==
<langsyntaxhighlight Fortranlang="fortran">module top
implicit none
contains
Line 955 ⟶ 1,024:
end do
end program
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
{{trans|XPL0:_Faster_Version}}
<syntaxhighlight lang="vb">Dim Shared As Byte n, d, best(16)
 
Sub TrySwaps(A() As Byte, f As Byte, s As Byte)
Dim As Byte B(16), i, j, k
If d > best(n) Then best(n) = d
Do
If A(s) = -1 Or A(s) = s Then Exit Do
If d+best(s) <= best(n) Then Exit Sub
If s = 0 Then Exit Do
s -= 1
Loop
d += 1
For i = 0 To s
B(i) = A(i)
Next
k = 1
For i = 1 To s
k Shl= 1
If B(i) =- 1 AndAlso (f And k) = 0 Or B(i) = i Then
j = i
B(0) = j
While j
j -= 1
B(i-j) = A(j)
Wend
TrySwaps(B(), f Or k, s)
End If
Next
d -= 1
End Sub
 
Dim As Byte i, X(16)
For i = 0 To 16-1
X(i) = -1
best(i) = 0
Next i
X(0) = 0
 
For n = 1 To 13
d = 0
TrySwaps(X(), 1, n-1)
Print Using "##: ##"; n; best(n)
Next n
 
Sleep</syntaxhighlight>
 
{{out}}
<pre> 1: 0
2: 1
3: 2
4: 4
5: 7
6: 10
7: 16
8: 22
9: 30
10: 38
11: 51
12: 65
13: 80</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">// Adapted from http://www-cs-faculty.stanford.edu/~uno/programs/topswops.w
// at Donald Knuth's web site. Algorithm credited there to Pepperdine
// and referenced to Mathematical Gazette 73 (1989), 131-133.
Line 1,012 ⟶ 1,146:
}
return m
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,029 ⟶ 1,163:
=={{header|Haskell}}==
====Searching permutations====
<langsyntaxhighlight Haskelllang="haskell">import Data.List (permutations)
 
topswops :: Int -> Int
Line 1,040 ⟶ 1,174:
 
main =
mapM_ (putStrLn . ((++) <$> show <*> (":\t" ++) . show . topswops)) [1 .. 10]</langsyntaxhighlight>
{{out}}
<pre>1: 0
Line 1,056 ⟶ 1,190:
'''Alternate version'''
<br>Uses only permutations with all elements out of place.
<langsyntaxhighlight Haskelllang="haskell">import Data.List (permutations, inits)
import Control.Arrow (first)
 
Line 1,075 ⟶ 1,209:
 
main :: IO ()
main = mapM_ print $ take 10 $ topSwops [1 ..]</langsyntaxhighlight>
'''Output'''
<pre>(1,0)
Line 1,093 ⟶ 1,227:
build the original list of 1..n values.
 
<langsyntaxhighlight lang="unicon">procedure main()
every n := 1 to 10 do {
ts := 0
Line 1,113 ⟶ 1,247:
if *A <= 1 then return A
suspend [(A[1]<->A[i := 1 to *A])] ||| permute(A[2:0])
end</langsyntaxhighlight>
 
Sample run:
Line 1,132 ⟶ 1,266:
 
=={{header|J}}==
'''Solution''':<langsyntaxhighlight lang="j"> swops =: ((|.@:{. , }.)~ {.)^:a:</langsyntaxhighlight>
'''Example''' (''from task introduction''):<langsyntaxhighlight lang="j"> swops 2 4 1 3
2 4 1 3
4 2 1 3
3 1 2 4
2 1 3 4
1 2 3 4</langsyntaxhighlight>
'''Example''' (''topswops of all permutations of the integers 1..10''):<langsyntaxhighlight lang="j"> (,. _1 + ! >./@:(#@swops@A. >:)&i. ])&> 1+i.10
1 0
2 1
Line 1,149 ⟶ 1,283:
8 22
9 30
10 38</langsyntaxhighlight>
'''Notes''': Readers less familiar with array-oriented programming may find [[Talk:Topswops#Alternate_J_solution|an alternate solution]] written in the structured programming style more accessible.
 
=={{header|Java}}==
{{trans|D}}
<langsyntaxhighlight lang="java">public class Topswops {
static final int maxBest = 32;
static int[] best;
Line 1,200 ⟶ 1,334:
System.out.println(i + ": " + topswops(i));
}
}</langsyntaxhighlight>
{{out}}
<pre>1: 0
Line 1,217 ⟶ 1,351:
 
'''Infrastructure:'''
<langsyntaxhighlight lang="jq"># "while" as defined here is included in recent versions (>1.4) of jq:
def until(cond; next):
def _until:
Line 1,236 ⟶ 1,370:
else
. as $n | ($n-1) | permutations | [$n-1, .] | insert
end;</langsyntaxhighlight>
'''Topswops:'''
<langsyntaxhighlight lang="jq"># Input: a permutation; output: an integer
def flips:
# state: [i, array]
Line 1,250 ⟶ 1,384:
def fannkuch:
reduce permutations as $p
(0; [., ($p|flips) ] | max);</langsyntaxhighlight>
 
'''Example:'''
<langsyntaxhighlight lang="jq">range(1; 11) | [., fannkuch ]</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq -n -c -f topswops.jq
[1,0]
[2,1]
Line 1,265 ⟶ 1,399:
[8,22]
[9,30]
[10,38]</langsyntaxhighlight>
 
=={{header|Julia}}==
Fast, efficient version
<langsyntaxhighlight lang="julia">function fannkuch(n)
n == 1 && return 0
n == 2 && return 1
Line 1,333 ⟶ 1,467:
end
end
end</langsyntaxhighlight>
{{out}}
<pre>julia> function main()
Line 1,358 ⟶ 1,492:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.2
 
val best = IntArray(32)
Line 1,392 ⟶ 1,526:
fun main(args: Array<String>) {
for (i in 1..10) println("${"%2d".format(i)} : ${topswops(i)}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,409 ⟶ 1,543:
 
=={{header|Lua}}==
<langsyntaxhighlight Lualang="lua">-- Return an iterator to produce every permutation of list
function permute (list)
local function perm (list, n)
Line 1,451 ⟶ 1,585:
-- Main procedure
for i = 1, 10 do print(i, topswops(i)) end</langsyntaxhighlight>
{{out}}
<pre>1 0
Line 1,464 ⟶ 1,598:
10 38</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
An exhaustive search of all possible permutations is done
<syntaxhighlight lang="mathematica">flip[a_] := Block[{a1 = First@a}, If[a1 == Length@a, Reverse[a], Join[Reverse[a[[;; a1]]], a[[a1 + 1 ;;]]]]]
<lang Mathematica>flip[a_] :=
Block[{a1 = First@a},
If[a1 == Length@a, Reverse[a],
Join[Reverse[a[[;; a1]]], a[[a1 + 1 ;;]]]]]
 
swaps[a_] := Length@FixedPointList[flip, a] - 2
Print[#, ": ", Max[swaps /@ Permutations[Range@#]]] & /@ Range[10];</syntaxhighlight>
 
Print[#, ": ", Max[swaps /@ Permutations[Range@#]]] & /@ Range[10];</lang>
{{out}}
<pre>1: 0
1: 0
2: 1
3: 2
Line 1,489 ⟶ 1,617:
=={{header|Nim}}==
{{trans|Java}}
<langsyntaxhighlight lang="nim">import strformat
 
const maxBest = 32
Line 1,528 ⟶ 1,656:
 
for i in 1..10:
echo &"{i:2}: {topswops(i):2}"</langsyntaxhighlight>
{{out}}
<pre>
Line 1,545 ⟶ 1,673:
=={{header|PARI/GP}}==
Naive solution:
<langsyntaxhighlight lang="parigp">flip(v:vec)={
my(t=v[1]+1);
if (t==2, return(0));
Line 1,558 ⟶ 1,686:
mx;
}
vector(10,n,topswops(n))</langsyntaxhighlight>
{{out}}
<pre>%1 = [0, 1, 2, 4, 7, 10, 16, 22, 30, 38]</pre>
Line 1,566 ⟶ 1,694:
=={{header|Perl}}==
Recursive backtracking solution, starting with the final state and going backwards.
<langsyntaxhighlight lang="perl">
sub next_swop {
my( $max, $level, $p, $d ) = @_;
Line 1,602 ⟶ 1,730:
 
printf "Maximum swops for %2d cards: %2d\n", $_, topswops $_ for 1..10;
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,620 ⟶ 1,748:
=={{header|Phix}}==
Originally contributed by Jason Gade as part of the Euphoria version of the Great Computer Language Shootout benchmarks.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function fannkuch(integer n)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence start = tagset(n),
<span style="color: #008080;">function</span> <span style="color: #000000;">fannkuch</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
perm,
<span style="color: #004080;">sequence</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span>
perm1 = start,
<span style="color: #000000;">perm1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
count = start
<span style="color: #004080;">integer</span> <span style="color: #000000;">maxFlipsCount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
integer maxFlipsCount = 0, r = n+1
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
integer perm0, flipsCount, k, k2, j, j2
<span style="color: #008080;">while</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
 
<span style="color: #000000;">count</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
while 1 do
<span style="color: #000000;">r</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
while r!=1 do count[r-1] = r r -= 1 end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
if not (perm1[1]=1 or perm1[n]=n) then
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">perm1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">perm1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
perm = perm1
<span style="color: #004080;">sequence</span> <span style="color: #000000;">perm</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perm1</span>
flipsCount = 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">flipsCount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
k = perm[1]
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
while k!=1 do
<span style="color: #008080;">while</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
k2 = floor((k+1)/2)
<span style="color: #000000;">perm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">perm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">perm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span>
perm = reverse(perm[1..k]) & perm[k+1..n]
<span style="color: #000000;">flipsCount</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perm</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
k = perm[1]
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">flipsCount</span><span style="color: #0000FF;">></span><span style="color: #000000;">maxFlipsCount</span> <span style="color: #008080;">then</span>
if flipsCount>maxFlipsCount then
<span style="color: #000000;">maxFlipsCount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">flipsCount</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #000080;font-style:italic;">-- Use incremental change to generate another permutation</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
while 1 do
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">></span><span style="color: #000000;">n</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">maxFlipsCount</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if r>n then return maxFlipsCount end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">perm0</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perm1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
perm0 = perm1[1]
<span style="color: #000000;">perm1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">r</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perm1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span>
j2 = 1
<span style="color: #000000;">perm1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">perm0</span>
while j2<r do
<span style="color: #000000;">count</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
j = j2+1
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
perm1[j2] = perm1[j]
<span style="color: #000000;">r</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
j2 = j
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
perm1[r] = perm0
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> <span style="color: #000080;font-style:italic;">-- fannkuch</span>
count[r] = count[r]-1
if count[r]>1 then exit else r += 1 end if
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
end while
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">:</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end while
<span style="color: #0000FF;">?</span><span style="color: #000000;">fannkuch</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
end function -- fannkuch
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
for i=1 to 10 do
<!--</syntaxhighlight>-->
? fannkuch(i)
end for</lang>
{{out}}
<pre>
Line 1,676 ⟶ 1,803:
30
38
"14.1s"
</pre>
It will manage 10 under pwa/p2js but with a blank screen for 38s, so I've capped it to 9 to make it finish in 3s.
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">go ?=>
member(N,1..10),
Perm = 1..N,
Rev = Perm.reverse(),
Max = 0,
while(Perm != Rev)
next_permutation(Perm),
C = topswops(Perm),
if C > Max then
Max := C
end
end,
printf("%2d: %2d\n",N,Max),
fail,
nl.
go => true.
 
topswops([]) = 0 => true.
topswops([1]) = 0 => true.
topswops([1|_]) = 0 => true.
topswops(P) = Count =>
Len = P.length,
Count = 0,
while (P[1] > 1)
Pos = P[1],
P := [P[I] : I in 1..Pos].reverse() ++ [P[I] : I in Pos+1..Len],
Count := Count + 1
end.
 
% Inline
next_permutation(Perm) =>
N = Perm.length,
K = N - 1,
while (Perm[K] > Perm[K+1], K >= 0)
K := K - 1
end,
if K > 0 then
J = N,
while (Perm[K] > Perm[J]) J := J - 1 end,
Tmp := Perm[K],
Perm[K] := Perm[J],
Perm[J] := Tmp,
R = N,
S = K + 1,
while (R > S)
Tmp := Perm[R],
Perm[R] := Perm[S],
Perm[S] := Tmp,
R := R - 1,
S := S + 1
end
end.</syntaxhighlight>
 
{{out}}
<pre> 1: 0
2: 1
3: 2
4: 4
5: 7
6: 10
7: 16
8: 22
9: 30
10: 38</pre>
 
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de fannkuch (N)
(let (Lst (range 1 N) L Lst Max)
(recur (L) # Permute
Line 1,693 ⟶ 1,889:
 
(for I 10
(println I (fannkuch I)) )</langsyntaxhighlight>
Output:
<pre>1 0
Line 1,708 ⟶ 1,904:
=={{header|PL/I}}==
{{incorrect|PL/I|Shown output is incorrect at the very least.}}
<syntaxhighlight lang="pl/i">
<lang PL/I>
(subscriptrange):
topswap: procedure options (main); /* 12 November 2013 */
Line 1,741 ⟶ 1,937:
end;
end topswap;
</syntaxhighlight>
</lang>
<pre>
1: 1
Line 1,756 ⟶ 1,952:
 
=={{header|Potion}}==
<langsyntaxhighlight lang="potion">range = (a, b):
i = 0, l = list(b-a+1)
while (a + i <= b):
Line 1,810 ⟶ 2,006:
if (n<1): n=10.
fannkuch(n)
</syntaxhighlight>
</lang>
 
Output follows that of Raku and Python, ~2.5x faster than perl5
Line 1,816 ⟶ 2,012:
=={{header|Python}}==
This solution uses cards numbered from 0..n-1 and variable p0 is introduced as a speed optimisation
<langsyntaxhighlight lang="python">>>> from itertools import permutations
>>> def f1(p):
i = 0
Line 1,841 ⟶ 2,037:
9 30
10 38
>>> </langsyntaxhighlight>
 
===Python: Faster Version===
{{trans|C}}
<langsyntaxhighlight lang="python">try:
import psyco
psyco.full()
Line 1,890 ⟶ 2,086:
 
for i in xrange(1, 13):
print "%2d: %d" % (i, topswops(i))</langsyntaxhighlight>
{{out}}
<pre> 1: 0
Line 1,907 ⟶ 2,103:
=={{header|R}}==
Using iterpc package for optimization
<syntaxhighlight lang="r">
<lang R>
topswops <- function(x){
i <- 0
Line 1,933 ⟶ 2,129:
result <- rbind(result, c(i, max(A$flips)))
}
</syntaxhighlight>
</lang>
 
Output:
Line 1,953 ⟶ 2,149:
Simple search, only "optimization" is to consider only all-misplaced permutations (as in the alternative Haskell solution), which shaves off around 2 seconds (from ~5).
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 1,971 ⟶ 2,167:
 
(for ([i (in-range 1 11)]) (printf "~a\t~a\n" i (topswops i)))
</syntaxhighlight>
</lang>
 
Output:
Line 1,989 ⟶ 2,185:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>sub swops(@a is copy) {
my int $count = 0;
until @a[0] == 1 {
Line 2,000 ⟶ 2,196:
sub topswops($n) { max (1..$n).permutations.race.map: &swops }
 
say "$_ {topswops $_}" for 1 .. 10;</langsyntaxhighlight>
{{Out}}
<pre>1 0
Line 2,015 ⟶ 2,211:
Alternately, using string manipulation instead. Much faster, though honestly, still not very fast.
 
<syntaxhighlight lang="raku" perl6line>sub swops($a is copy) {
my int $count = 0;
while (my \l = $a.ord) > 1 {
Line 2,026 ⟶ 2,222:
sub topswops($n) { max (1..$n).permutations.map: { .chrs.join.&swops } }
 
say "$_ {topswops $_}" for 1 .. 10;</langsyntaxhighlight>
 
Same output
Line 2,033 ⟶ 2,229:
The &nbsp; '''decks''' &nbsp; function is a modified permSets (permutation sets) subroutine,
<br>and is optimized somewhat to take advantage by eliminating one-swop "decks".
<langsyntaxhighlight lang="rexx">/*REXX program generates N decks of numbered cards and finds the maximum "swops". */
parse arg things .; if things=='' then things= 10
 
do n=1 for things; #= decks(n, n) /*create a (things) number of "decks". */
mx= (n\==1) /*handle the case of a one-card deck.*/
do i=1 for #; p= swops(!.i) /*compute the SWOPS for this iteration.*/
if p>mx then mx=p p /*This a new maximum? Use a new max. */
end /*i*/
say '──────── maximum swops for a deck of' right(n,2) ' cards is' right(mx,4)
end /*n*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
decks: procedure expose !.; parse arg x,y,,$ @. /* X things taken Y at a time. */
#= 0; call .decks 1 /* [↑] initialize $ & @. to null.*/
return # /*return number of permutations (decks)*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
.decks: procedure expose !. @. x y $ #; parse arg ?
if ?>y then do; _=@.1; do j=2 for y-1; _= _ @.j; end /*j*/; #= #+1; !.#=_
end
else do; qm= ? - 1
if ?==1 then qs=2 2 /*don't use 1-swops that start with 1 */
else if @.1==? then qs=2 /*skip the 1-swops: 3 x 1 x ···*/
else qs=1
do q=qs to x /*build the permutations recursively. */
do k=1 for qm; if @.k==q then iterate q
end /*k*/
@.?=q; ; call .decks ? + 1
end /*q*/
end
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
swops: parse arg z; do u=1; parse var z t .; if \datatype(t, 'W') then t= x2d(t)
 
swops: parse arg z; do u=1; parse var z t .; if \datatypeword(tz, 'W't)==1 then t=x2d(t)return u /*found unity at T. */
if word(z, t)==1 then return u do h=10 to things; if pos(h, /*foundz)==0 unity at T.then */iterate
doz= changestr(h=10, z, tod2x(h) things;) if pos(h, z)==0 then/* [↑] any H's in iterateZ?*/
z=changestr(h, z, d2x(h) ) /* [↑] any H's in Z?*/
end /*h*/
z= reverse( subword(z, 1, t) ) subword(z, t + 1)
end /*u*/</langsyntaxhighlight>
Some older REXXes don't have a &nbsp; '''changestr''' bif&nbsp; BIF, &nbsp; so one is included here &nbsp; ───► &nbsp; [[CHANGESTR.REX]].
{{out|output|text=&nbsp; when using the default input:}}
Line 2,089 ⟶ 2,285:
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">def f1(a)
i = 0
while (a0 = a[0]) > 1
Line 2,104 ⟶ 2,300:
for n in 1..10
puts "%2d : %d" % [n, fannkuch(n)]
end</langsyntaxhighlight>
 
{{out}}
Line 2,122 ⟶ 2,318:
'''Faster Version'''
{{trans|Java}}
<langsyntaxhighlight lang="ruby">def try_swaps(deck, f, d, n)
@best[n] = d if d > @best[n]
(n-1).downto(0) do |i|
Line 2,152 ⟶ 2,348:
for i in 1..10
puts "%2d : %d" % [i, topswops(i)]
end</langsyntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
use itertools::Itertools;
 
fn solve(deck: &[usize]) -> usize {
let mut counter = 0_usize;
let mut shuffle = deck.to_vec();
loop {
let p0 = shuffle[0];
if p0 == 1 {
break;
}
shuffle[..p0].reverse();
counter += 1;
}
 
counter
}
 
// this is a naive method which tries all permutations and works up to ~12 cards
fn topswops(number: usize) -> usize {
(1..=number)
.permutations(number)
.fold(0_usize, |mut acc, p| {
let steps = solve(&p);
if steps > acc {
acc = steps;
}
acc
})
}
fn main() {
(1_usize..=10).for_each(|x| println!("{}: {}", x, topswops(x)));
}
</syntaxhighlight>
{{out}}
<pre>
1: 0
2: 1
3: 2
4: 4
5: 7
6: 10
7: 16
8: 22
9: 30
10: 38
</pre>
 
=={{header|Scala}}==
{{libheader|Scala}}<langsyntaxhighlight Scalalang="scala">object Fannkuch extends App {
 
def fannkuchen(l: List[Int], n: Int, i: Int, acc: Int): Int = {
Line 2,186 ⟶ 2,431:
assert(result == Vector((1, 0), (2, 1), (3, 2), (4, 4), (5, 7), (6, 10), (7, 16), (8, 22), (9, 30), (10, 38)), "Bad results")
println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
}</langsyntaxhighlight>{{out}}
Computing results...
Pfannkuchen(1) = 0
Line 2,204 ⟶ 2,449:
=={{header|Tcl}}==
{{tcllib|struct::list}}<!-- Note that struct::list 1.8.1 (and probably earlier too) has a bug which makes this code hang when computing topswops(10). -->Probably an integer overflow at n=10.
<langsyntaxhighlight lang="tcl">package require struct::list
 
proc swap {listVar} {
Line 2,237 ⟶ 2,482:
}
}
topswopsTo 10</langsyntaxhighlight>{{out}}
n topswops(n)
1 0
Line 2,253 ⟶ 2,498:
{{trans|Go}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var maxn = 10
Line 2,302 ⟶ 2,547:
}
 
for (i in 1..maxn) Fmt.print("$2d: $d", i, steps.call(i))</langsyntaxhighlight>
 
{{out}}
Line 2,319 ⟶ 2,564:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code ChOut=8, CrLf=9, IntOut=11;
int N, Max, Card1(16), Card2(16);
 
Line 2,355 ⟶ 2,600:
IntOut(0, N); ChOut(0, ^ ); IntOut(0, Max); CrLf(0);
];
]</langsyntaxhighlight>
 
{{out}}
Line 2,374 ⟶ 2,619:
{{trans|C}}
 
<langsyntaxhighlight XPL0lang="xpl0">code CrLf=9, IntOut=11, Text=12;
int N, D, Best(16);
Line 2,409 ⟶ 2,654:
IntOut(0, N); Text(0, ": "); IntOut(0, Best(N)); CrLf(0);
];
]</langsyntaxhighlight>
 
{{out}}
Line 2,431 ⟶ 2,676:
{{trans|D}}
Slow version
<langsyntaxhighlight lang="zkl">fcn topswops(n){
flip:=fcn(xa){
if (not xa[0]) return(0);
Line 2,440 ⟶ 2,685:
}
 
foreach n in ([1 .. 10]){ println(n, ": ", topswops(n)) }</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits