Konstruiere einen Permuter

9

Für diese Herausforderung erstellen Sie eine Funktion (Ihre Funktion kann ein vollständiges Programm sein), die eine Liste als Eingabe verwendet und eine Permutation dieser Liste zurückgibt. Ihre Funktion muss die folgenden Anforderungen erfüllen.

  • Es muss deterministisch sein.

  • Wenn Sie Ihre Funktion mit einer variablen Anzahl von Malen zusammensetzen, sollte eine Liste mit beliebigen Permutationen erstellt werden können.

Dies ist eine Code-Golf-Frage, daher werden die Antworten in Bytes bewertet, wobei weniger Bytes besser sind.

Weitere Regeln

  • Sie können jede Art von Liste nehmen, ( [Integer], [String], [[Integer]]), solange es

    • Kann nicht leer sein
    • Kann verschiedene Objekte mit mindestens 16 möglichen Werten enthalten. (Sie können kein Haskell verwenden [()]und behaupten, Ihre Funktion sei id)
    • Kann doppelte Objekte enthalten (keine Mengen)
  • Sie können ein Programm oder eine Funktion schreiben, müssen jedoch die Standard-E / A befolgen.

Ad-hoc-Garf-Jäger
quelle
Ist S_naber nur zyklisch fürn<3
Leaky Nun
@LeakyNun, es wird nicht nach einer einzelnen Permutation gefragt, die die symmetrische Gruppe erzeugt, sondern nach einer next_permutationFunktion.
Peter Taylor
Würde es ausreichen, nur Listen mit Nullen und Einsen zu permutieren?
xnor
Ich bin mir nicht sicher, ob ich den Sinn dieser Einschränkung verstehe. Wenn Sie Listen von Booleschen Werten zulassen, was bringt es, Iterables über zwei unterschiedliche Elemente nicht zuzulassen?
Dennis
@ Tennis Du machst einen guten Punkt. Ich werde Listen von Booleschen Werten nicht zulassen. Oder Typen mit weniger als 16 möglichen Werten.
Ad-hoc-Garf-Jäger

Antworten:

4

CJam (11 Bytes)

{_e!_@a#(=}

Online-Demo mit dem vollständigen Zyklus für eine Liste mit vier Elementen und einem doppelten Element.

Präparation

{      e# Define a block
  _e!  e#   Find all permutations of the input. Note that if there are duplicate
       e#   elements in the input then only distinct permutations are produced.
       e#   Note also that the permutations are always generated in lexicographic
       e#   order, so the order is independent of the input.
  _@a# e#   Find the index of the input in the list
  (=   e#   Decrement and get the corresponding element of the list
       e#   Incrementing would also have worked, but indexing by -1 feels less
       e#   wrong than indexing by the length, and makes this more portable to
       e#   GolfScript if it ever adds a "permutations" built-in
}
Peter Taylor
quelle
2

Mathematica + Combinatorica (integriertes Paket) 34 Bytes

19 Bytes zum Laden des Pakets und 15 Bytes für die Funktion.

<<"Combinatorica`";NextPermutation

Verwendungszweck:

%@{c, b, a}

Ohne die eingebauten 61 Bytes

Extract[s=Permutations[Sort@#],Mod[s~Position~#+1,Length@s]]&

Combinatorica soll vollständig in Mathematica integriert sein, aber ich denke, die NextPermutation-Funktion wurde übersehen.

Kelly Lowder
quelle
2

C ++, 42 Bytes

#include <algorithm>
std::next_permutation

Diese genaue Operation ist in C ++ integriert.

orlp
quelle
2
Warum der Raum danach #include?
Yytsi
2

JavaScript (ES6), 145 139 137 134 108 Byte

Dank @Neil satte 25 Bytes gespart!

Übernimmt die Eingabe als Array von alphabetischen Zeichen. Gibt die nächste Permutation als anderes Array zurück.

a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,a.concat(a.splice(x+1).sort()))

Wie?

Dies ist eine Generation in lexikografischer Reihenfolge , die bei jeder Iteration die folgenden 4 Schritte verarbeitet:

  1. Finden Sie den größten Index X so, dass a [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Finden Sie den größten Index Y größer als X, so dass a [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Tauschen Sie den Wert von a [X] gegen den von a [Y] aus.

    a[x] = a[y], a[y] = t
  4. Sortieren Sie die Sequenz von [X + 1] bis einschließlich des letzten Elements in aufsteigender lexikografischer Reihenfolge

    a.concat(a.splice(x + 1).sort())

Beispiel:

Schritte

Demo

Arnauld
quelle
Kannst du nicht sortieren anstatt umzukehren? Ich denke auch, dass v<a[i+1]&&(t=v,x=i)ein Byte gespart wird und Sie möglicherweise mehr Einsparungen spliceanstelle von zwei sliceSekunden erzielen können.
Neil
@Neil Guter Fang!
Arnauld
Ich glaube, ich konnte die beiden mapauch für 112 Bytes zusammenführen:a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,t=a.splice(++x).sort(),a.concat(t))
Neil
Ich muss zugeben, ich hätte nicht gedacht a.concat(a.splice(++x).sort()), dass es funktionieren würde, sonst hätte ich es versucht ...
Neil
@Neil Danke! Aktualisiert. (Mit 4 weiteren Bytes gespeichert, weil wir nicht wirklich t müssen , um () zu concat () ).
Arnauld
1

Gelee , 6 Bytes

Œ¿’œ?Ṣ

Durchläuft die Permutationen in absteigender lexikografischer Reihenfolge.

Probieren Sie es online aus!

Wie es funktioniert

Œ¿’œ?Ṣ  Main link. Argument: A (array)

Œ¿      Compute the permutation index n of A, i.e., the index of A in the
        lexicographically sorted list of permutations of A.
  ’     Decrement the index by 1, yielding n-1.
     Ṣ  Sort A.
   œ?   Getthe (n-1)-th permutation of sorted A.
Dennis
quelle
1

C 161 Bytes

Tatsächlicher O (n) -Algorithmus.

#define S(x,y){t=x;x=y;y=t;}
P(a,n,i,j,t)int*a;{for(i=n;--i&&a[i-1]>a[i];);for(j=n;i&&a[--j]<=a[i-1];);if(i)S(a[i-1],a[j])for(j=0;j++<n-i>>1;)S(a[i+j-1],a[n-j])}

Anwendungsbeispiel:

int main(int argc, char** argv) {
    int i;
    int a[] = {1, 2, 3, 4};

    for (i = 0; i < 25; ++i) {
        printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
        P(a, 4);
    }

    return 0;
}
orlp
quelle
1

Python 2 , 154 Bytes

x=input()
try:exec'%s=max(k for k in range(%s,len(x))if x[%s-1]<x[k]);'*2%tuple('i1kjii');x[i-1],x[j]=x[j],x[i-1];x[i:]=x[:i-1:-1]
except:x.sort()
print x

Probieren Sie es online aus!

Dennis
quelle
Ich denke, dies ist kürzer als eine Funktion, die die Liste an Ort und Stelle permutiert.
Orlp
Ich habe das versucht, aber execmir alle möglichen Fehler in einer Funktion gegeben
Dennis
0

Gelee , 10 Bytes

ṢŒ!Q©i⁸‘ị®

Probieren Sie es online aus!

Sortieren> Alle Permutation> Eingabe suchen> 1 hinzufügen> Index in "Alle Permutation"

Undichte Nonne
quelle
@ PeterTaylor Ich habe es behoben.
Undichte Nonne
Es gibt spezielle integrierte Funktionen für Permutationen (dh Sie können dies einfach tun Œ¿‘œ?Ṣ). Ich hatte seitdem keine Lust mehr zu stehlen.
Erik der Outgolfer
@EriktheOutgolfer Für Eingaben, die Duplikate enthalten, ist es möglicherweise etwas chaotisch.
Undichte Nonne
Hmm ... ich denke schon, ich hatte eine Version, die vorher dafür funktioniert hat, aber Sie scheinen das QDing zu benutzen . Sie können immer noch Golf spielen ṢŒ!Qµi³‘ị.
Erik der Outgolfer
0

PHP , 117 Bytes

Nimmt Eingabe / Ausgabe als Zeichenfolgenliste der unteren Buchstaben

$a=str_split($s=$argn);rsort($a);if(join($a)!=$s)for($n=$s;($c=count_chars)(++$n)!=$c($s););else$n=strrev($s);echo$n;

Probieren Sie es online aus!

Jörg Hülsermann
quelle