Étapes de permutation

10

Écrivez une fonction qui prend un ensemble d'entiers et imprime chaque permutation de l'ensemble, et l'échange effectué entre chaque étape

Contribution

un ensemble d'entiers, par exemple (0, 1, 2)

Production

la liste des permutations et swaps au format (set) (swap) (set) ...

Cas de test

Input: 
(3, 1, 5)

Output:
(3, 1, 5)
(3, 1)
(1, 3, 5)
(3, 5)
(1, 5, 3)
(1, 3)
(3, 5, 1)
(3, 5)
(5, 3, 1)
(3, 1)
(5, 1, 3)

Règles

  • Vous pouvez formater l'ensemble de nombres comme vous le souhaitez.
  • Vous pouvez effectuer les swaps dans n'importe quel ordre
  • Vous pouvez répéter les permutations et les échanges afin d'en obtenir un nouveau
  • Votre code n'a pas besoin d'effectuer les échanges, la sortie doit simplement montrer quel échange a été effectué entre votre dernière sortie et votre sortie actuelle
  • Votre code ne doit fonctionner que pour les ensembles de 2 éléments ou plus
  • L'ensemble qui vous est fourni n'aura aucun élément répétitif (par exemple (0, 1, 1, 2) n'est pas valide)

C'est le code-golf, donc le code le plus court gagne!

Billyoyo
la source
Pouvons-nous utiliser le hasard?
Zgarb
Vous voulez juste faire une charge de swaps aléatoires jusqu'à ce que vous obteniez toutes les permutations? Oui, mais vous devez être sûr que toutes les permutations ont été imprimées
Billyoyo
3
Bienvenue chez PPCG! Beau premier défi. Je suggérerais de modifier l'exemple afin que les éléments ne soient pas confondus avec les indices, comme use set (3, 1, 4)ou autre - le lire la première fois, j'étais très confus parce que le premier échange a 0,1permuté les éléments 0,1mais aussi les indices 0,1, mais ensuite le suivant l'échange n'a pas suivi ce schéma. Je vous indiquerai également le bac à sable où vous pouvez publier des défis et obtenir des commentaires avant de les publier sur le site principal.
AdmBorkBork
2
@TimmyD merci pour la suggestion, j'ai changé l'exemple. J'ai vu le lien vers le bac à sable juste après avoir posté cela, je vais y poster dès maintenant!
Billyoyo
1
L' algorithme Steinhaus – Johnson – Trotter génère la séquence minimale nécessaire.
Neil

Réponses:

3

Mathematica, 102 octets

<<Combinatorica`
Riffle[#,BlockMap[Pick[#[[1]],#!=0&/@({1,-1}.#)]&,#,2,1]]&@*MinimumChangePermutations

Exemples

// Colonne pour un résultat plus clair

%[{1,3,5}]//Column
(*
{1,3,5}
{1,3}
{3,1,5}
{3,5}
{5,1,3}
{5,1}
{1,5,3}
{1,3}
{3,5,1}
{3,5}
{5,3,1}
*)
njpipeorgan
la source
3

Java, 449 426 octets

import java.util.*;interface P{static Set s=new HashSet();static void main(String[]a){o(Arrays.toString(a));while(s.size()<n(a.length)){p(a);o(Arrays.toString(a));}}static<T>void o(T z){System.out.println(z);s.add(z);}static int n(int x){return x==1?1:x*n(x-1);}static void p(String[]a){Random r=new Random();int l=a.length,j=r.nextInt(l),i=r.nextInt(l);String t=a[j];a[j]=a[i];a[i]=t;System.out.println("("+a[j]+","+t+")");}}

Approche par force brute. Il continue à effectuer des échanges aléatoires jusqu'à ce que toutes les permutations possibles aient eu lieu. Il utilise un ensemble de la représentation sous forme de chaîne du tableau afin de vérifier combien d'états différents ont été générés. Pour n entiers différents, il y a n! = 1 * 2 * 3 * .. * n permutations distinctes.

Mise à jour

  • J'ai suivi les suggestions de Kevin Cruijssen pour jouer au golf un peu plus.

Non golfé:

import java.util.*;

interface P {

    static Set<String> s = new HashSet<>();

    static void main(String[] a) {
        // prints the original input
        o(Arrays.toString(a));
        while (s.size() < n(a.length)) {
            p(a);
            // prints the array after the swap
            o(Arrays.toString(a));
        }
    }

    static void o(String z) {
        System.out.println(z);
        // adds the string representation of the array to the HashSet
        s.add(z);
    }

    // method that calculates n!
    static int n(int x) {
        if (x == 1) {
            return 1;
        }
        return x * n(x - 1);
    }

    // makes a random swap and prints what the swap is
    static void p(String[] a) {
        Random r = new Random();
        int l = a.length, j = r.nextInt(l), i = r.nextInt(l);
        String t = a[j];
        a[j] = a[i];
        a[i] = t;
        System.out.println("(" + a[j] + "," + t + ")");
    }
}

Usage:

$ javac P.java
$ java P 1 2 3
[1, 2, 3]
(2,1)
[2, 1, 3]
(1,1)
[2, 1, 3]
(2,2)
[2, 1, 3]
(3,1)
[2, 3, 1]
(3,1)
[2, 1, 3]
(1,2)
[1, 2, 3]
(1,1)
[1, 2, 3]
(3,2)
[1, 3, 2]
(2,3)
[1, 2, 3]
(3,1)
[3, 2, 1]
(3,1)
[1, 2, 3]
(3,3)
[1, 2, 3]
(1,2)
[2, 1, 3]
(1,3)
[2, 3, 1]
(1,2)
[1, 3, 2]
(3,1)
[3, 1, 2]

Comme vous pouvez le voir, il y a beaucoup plus de swaps que le minimum nécessaire. Mais cela semble fonctionner :-D

En prime, cela fonctionne aussi avec les chaînes, c'est-à-dire

$ java P 'one' 'two'
[one, two]
(two,one)
[two, one]
Master_ex
la source
avez-vous une version non-golfée pour que nous puissions examiner votre méthode en utilisant?
Billyoyo
@Billyoyo: Ajout du code non golfé. Rien d'extraordinaire cependant :-)
Master_ex
Vous pouvez jouer au golf un peu. Pas besoin d'avertissements de correctifs, vous pouvez supprimé les déclarations Set: Set s=new HashSet();. Votre code dans la méthode npeut être un retour simple: static int n(int x){return x==1?1:x*n(x-1);}. Et vous pouvez remplacer String zdans votre méthode oavec un lieu générique: static<T>void o(T z){System.out.println(z);s.add(z);}. Combiné, il atteindrait 426 octets .
Kevin Cruijssen
1

JavaScript (ES6), 186 octets

f=
a=>{console.log(a);d=a.slice().fill(-1);s=[...d.keys()];for(i=l=a.length;i;)s[k=(j=s.indexOf(--i))+d[i]]<i?(console.log(a[s[j]=s[k]],a[s[k]=i]),console.log(s.map(n=>a[n])),i=l):d[i]*=-1}
;
<input id=i><input type=button value=Go! onclick=f(i.value.split`,`)>

Remarque: je ne suis pas sûr de la flexibilité du format de sortie, peut-être que je pourrais le faire pour 171 octets:

a=>{console.log(a);d=a.slice().fill(-1);s=[...d.keys()];for(i=l=a.length;i;)s[k=(j=s.indexOf(--i))+d[i]]<i?console.log(a[s[j]=s[k]],a[s[k]=i],s.map(n=>a[n],i=l)):d[i]*=-1}

Fonctionne en exécutant l' algorithme Steinhaus – Johnson – Trotter sur le tableau aléatoire d'index et en effectuant une conversion vers le tableau d'entrée. Non golfé:

function steps(array) {
    console.log(array); // initial row
    var d = a.slice().fill(-1); // direction values
    var s = [...a.keys()]; // initial (identity) shuffle
    var l = a.length;
    for (var i = l; i; ) { // start by trying to move the last element
        var j = s.indexOf(--i);
        var k = j + d[i]; // proposed exchange
        if (s[k] < i) { // only exchange with lower index (within bounds)
            console.log(a[s[k]],a[i]); // show values being exchanged
            s[j] = s[k];
            s[k] = i; // do the exchange on the shuffle
            console.log(s.map(n=>a[n])); // show the shuffled array
            i = l; // start from the last element again
        } else {
            d[i] *= -1; // next time, try moving it the other way
        } // --i above causes previous element to be tried
    } // until no movable elements can be found
}
Neil
la source
1

Rubis, 86 octets

puts (2..(a=gets.scan(/\d+/).uniq).size).map{|i|a.permutation(i).map{|e|?(+e*", "+?)}}
cia_rana
la source
1

Haskell - 135 octets

p=permutations;f=filter
q(a:b:xs)=(\x->f(uncurry(/=)).zip x)a b:q(b:xs);q _=[]
l=head.f(all((==2).length).q).p.p
f=zip.l<*>map head.q.l

production:

> f [3,1,5]
[([3,1,5],(3,1)),([1,3,5],(3,5)),([1,5,3],(1,5)),([5,1,3],(1,3)),([5,3,1],(5,3))]

J'utilise la permutationsfonction standard , qui n'est pas basée sur les swaps, donc je prends les permutations des permutations et j'en trouve une qui se trouve être une chaîne de swaps.

BlackCap
la source