Passi di permutazione


10

Scrivi una funzione che accetta un insieme di numeri interi e stampa ogni permutazione dell'insieme e lo scambio eseguito tra ogni passaggio

Ingresso

un insieme di numeri interi, ad esempio (0, 1, 2)

Produzione

l'elenco di permutazioni e swap nel formato (set) (swap) (set) ...

Caso di prova

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)

Regole

  • È possibile formattare l'insieme di numeri come desiderato.
  • Puoi effettuare gli swap in qualsiasi ordine
  • Puoi ripetere permutazioni e scambi per ottenerne uno nuovo
  • Il codice non deve effettivamente eseguire gli swap, l'output deve solo mostrare quale swap è stato effettuato tra l'ultimo output e quello corrente
  • Il tuo codice deve funzionare solo per set con 2 o più elementi
  • Il set che ti viene dato non avrà elementi ripetitivi (es. (0, 1, 1, 2) non è valido)

Questo è code-golf, quindi vince il codice più corto!


Possiamo usare la casualità?
Zgarb,

Intendi semplicemente fare un carico di scambi casuali fino a quando non ti capita di raggiungere tutte le permutazioni? Sì, ma devi essere sicuro che tutte le permutazioni sono state stampate
Billyoyo,

3
Benvenuti in PPCG! Bella prima sfida. Suggerirei di modificare l'esempio in modo che gli elementi non si confondano con gli indici, come use set (3, 1, 4)o giù di lì - leggendolo la prima volta sono stato molto confuso perché il primo swap ha 0,1scambiato gli elementi 0,1ma anche gli indici 0,1, ma poi il successivo lo swap non ha seguito questo schema. Ti indicherò anche il Sandbox dove puoi pubblicare le sfide e ottenere feedback prima di pubblicarle sul sito principale.
AdmBorkBork,

2
@TimmyD grazie per il suggerimento, ho cambiato l'esempio. Ho visto il link alla sandbox subito dopo averlo pubblicato, lo posterò prima d'ora in poi!
Billyoyo,

1
L' algoritmo Steinhaus – Johnson – Trotter genera la sequenza minima necessaria.
Neil,

Risposte:


3

Mathematica, 102 byte

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

Esempi

// Colonna per un risultato più chiaro

%[{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}
*)

3

Java, 449 426 byte

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+")");}}

Approccio a forza bruta. Continua a fare scambi casuali fino a quando tutte le possibili permutazioni hanno avuto luogo. Utilizza un insieme di rappresentazioni di stringhe dell'array per verificare quanti stati diversi sono stati generati. Per n numeri interi diversi ci sono n! = 1 * 2 * 3 * .. * n permutazioni distinte.

Aggiornare

  • Ho seguito i suggerimenti di Kevin Cruijssen per giocarci ancora un po '.

Ungolfed:

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 + ")");
    }
}

Uso:

$ 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]

Come puoi vedere ci sono molti più swap del minimo necessario. Ma sembra funzionare MrGreen

Come bonus, funziona anche con le stringhe, ad es

$ java P 'one' 'two'
[one, two]
(two,one)
[two, one]

hai una versione non giocata per noi per dare un'occhiata al tuo metodo usando?
Billyoyo,

@Billyoyo: aggiunto il codice non golf. Niente di speciale, comunque :-)
Master_ex

Puoi giocare a golf un po '. Non c'è bisogno di avvertimenti fix, in modo da poter rimuovere i Set dichiarazioni: Set s=new HashSet();. Il tuo codice nel metodo npuò essere un singolo di ritorno: static int n(int x){return x==1?1:x*n(x-1);}. E si può sostituire String znel metodo ocon invece un generico: static<T>void o(T z){System.out.println(z);s.add(z);}. Tutto sommato si ridurrebbe a 426 byte .
Kevin Cruijssen,

1

JavaScript (ES6), 186 byte

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`,`)>

Nota: non sono sicuro di quanto sia flessibile il formato di output, forse potrei farlo per 171 byte:

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}

Funziona eseguendo l' algoritmo Steinhaus – Johnson – Trotter sulla matrice di indici shuffle e traducendo nuovamente nella matrice di input. Ungolfed:

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
}

1

Rubino, 86 byte

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

1

Haskell - 135 byte

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

produzione:

> 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))]

Sto usando la permutationsfunzione standard , che non si basa sugli swap, quindi prendo le permutazioni delle permutazioni e trovo una che sembra essere una catena di swap.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.