Generieren Sie den Satz von Prepend-Append-Permutationen in lexikografisch sortierter Reihenfolge

14

Definieren Sie eine Präpend-Append-Sequenz mit einer Länge nals Permutation der Zahlen 1, 2, ..., n, die mit der folgenden Prozedur generiert werden können:

  • Beginnen Sie mit der Nummer 1.

  • Platzieren Sie diese Nummer für jede Nummer von 2bis nan den Anfang oder das Ende der Sequenz (entweder voranstellen oder anhängen , daher der Name der Sequenz).

Dies ist beispielsweise eine gültige Methode zum Generieren einer Prepend-Append-Sequenz der Länge 4:

1
21     [beginning]
213    [end]
2134   [end]

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu erstellen, die eine Zahl nvon 3bis 30als Eingabe verwendet und alle nlexikografischen Längenfolgen mit vorangestelltem Anhang ausgibt oder zurückgibt (wenn Sie Zeichenfolgen und keine Listen ausgeben, werden Zahlen über 9 dargestellt) als Buchstaben a-u, um die Länge der Zeichenkette zu erhalten). Zum Beispiel ist dies die Reihenfolge für n = 4:

1234  [RRR]
2134  [LRR]
3124  [RLR]
3214  [LLR]
4123  [RRL]
4213  [LRL]
4312  [RLL]
4321  [LLL]

Im Allgemeinen gibt es 2 n-1 Prepend-Append-Permutationen mit einer Länge n.

Sie dürfen in Ihrem Code keine in Ihrer Sprache integrierten Sortierfunktionen verwenden. Das kürzeste Programm, um dies in einer Sprache zu tun, gewinnt.

Joe Z.
quelle
Ich bin kein Fan des Ausgabeformats, insbesondere der Konvertierung in Buchstaben a-u. Können wir nur Zahlenlisten ausgeben?
Xnor
3
Möglicherweise möchten Sie die Antwort nach einiger Zeit akzeptieren, da einige Personen dazu neigen, eine Frage nicht zu beantworten, wenn sie eine akzeptierte Antwort hat.
Optimierer
1
Sie haben also die Antwort falsch angenommen.
Optimierer
2
FryAmTheEggman hat seine Antwort 21 Minuten, bevor Sie Ihre bearbeitet haben, veröffentlicht.
Joe Z.
2
@Optimizer Ich glaube nicht, dass es der seltsamste Weg ist - FryAmTheEggmans Antwort war 21 Minuten vor Ihrer 19 Byte lang. Damit ist es die am frühesten gepostete kürzeste Antwort.
Joe Z.

Antworten:

10

CJam, 22 20 19 17 Bytes

]]l~{)f+_1fm>|}/p

Code-Erweiterung :

]]                   "Put [[]] onto stack. What we will do with this array of array is";
                     "that in each iteration below, we will first append the next";
                     "number to all present arrays, then copy all the arrays and";
                     "move the last element to first in the copy";
  l~                 "Read input number. Lets call it N";
    {         }/     "Run this code block N times ranging from 0 to N - 1";
     )f+             "Since the number on stack starts from 0, add 1 to it and append";
                     "it to all arrays in the array of array beginning with [[]]";
        _1fm>        "Copy the array of array and move last element from all arrays";
                     "to their beginning";
             |       "Take set union of the two arrays, thus joining them and eliminating";
                     "duplicates. Since we started with and empty array and started adding";
                     "numbers from 1 instead of 2, [1] would have appeared twice if we had";
                     "simply done a concat";
                p    "Print the array of arrays";

Wie es funktioniert :

Dies ist eine Debug-Version des Codes:

]]l~ed{)edf+ed_ed1fm>ed|ed}/edp

Mal sehen, wie es bei der Eingabe funktioniert 3:

[[[]] 3]                                 "]]l~"            "Empty array of array and input";
[[[]] 1]                                 "{)"              "First iteration, increment 0";
[[[1]]]                                  "{)f+"            "Append it to all sub arrays";
[[[1]] [[1]]]                            "{)f+_"           "Copy the final array of array";
[[[1]] [[1]]]                            "{)f+_1fm>"       "shift last element of each";
                                                           "sub array to the beginning";
[[[1]]]                                  "{)f+_1fm>|}"     "Take set based union";
[[[1]] 2]                                "{)"              "2nd iteration. Repeat";
[[[1 2]]]                                "{)f+"
[[[1 2]] [[1 2]]]                        "{)f+_";
[[[1 2]] [[2 1]]]                        "{)f+_1fm>";
[[[1 2] [2 1]]]                          "{)f+_1fm>|}";
[[[1 2] [2 1]] 3]                        "{)";
[[[1 2 3] [2 1 3]]]                      "{)f+"
[[[1 2 3] [2 1 3]] [[1 2 3] [2 1 3]]]    "{)f+_";
[[[1 2 3] [2 1 3]] [[3 1 2] [3 2 1]]]    "{)f+_1fm>";
[[[1 2 3] [2 1 3] [3 1 2] [3 2 1]]]      "{)f+_1fm>|}";
[[[1 2 3] [2 1 3] [3 1 2] [3 2 1]]]      "{)f+_1fm>|}/";

Probieren Sie es hier online aus

Optimierer
quelle
6

Haskell, 47 Bytes

f 1=[[1]]
f n=(\x->map(++[n])x++map(n:)x)$f$n-1
Alephalpha
quelle
1
Durch das Umschalten auf Listenverständnis werden einige Bytes gespart: f n=[[n:x,x++[n]]|x<-f$n-1]>>=id(mit der Code-Golfer-Concat-Funktion >>=id).
Nimi
1
@ Nimi, aber es ist in der falschen Reihenfolge R
stolzer Haskeller
@ proudhaskeller: Oh je, habe die Spezifikation nicht sorgfältig genug gelesen. Ich habe versucht, das Problem zu beheben, und dabei vier leicht unterschiedliche Methoden gefunden, die alle die gleiche Länge wie die Version von @ alephalpha haben. Daher kann ich keine Verbesserung anbieten. f n=[x++[n]|x<-f$n-1]++[n:x|x<-f$n-1], f n=map(++[n])(f$n-1)++[n:x|x<-f$n-1], f n=map(++[n])(f$n-1)++map(n:)(f$n-1),f n=(++[n])#n++(n:)#n;p#i=map p$f$i-1
nimi
5

Python 2, 68

f=lambda n:[[1]]*(n<2)or[x*b+[n]+x*-b for b in[1,-1]for x in f(n-1)]

Gibt eine Liste mit Nummernlisten aus.

Eine rekursive Lösung. Für n==1Ausgabe [[1]]. Fügen Sie andernfalls nden Anfang oder das Ende aller (n-1)-Permutationen hinzu. Beim Voranstellen wird die Permutation später lexikografisch als beim Anhängen, sodass die Permutationen sortiert bleiben.

Der "Boolesche Wert" bkodiert, ob [n]am Anfang oder am Ende gesetzt werden soll. Tatsächlich verschieben wir den Rest der Liste xim Ausdruck x*b+[n]+x*-b. Putting bas -1oder 1lets use flip by negating, da eine mit multiplizierte Liste -1die leere Liste ist.

xnor
quelle
4

Pyth, 19

usCm,+dH+HdGr2hQ]]1

Probieren Sie es hier online aus

Dies ist ein vollständiges Programm, das Eingaben von stdin akzeptiert.

Dies funktioniert auf ähnliche Weise wie die Lösung von xnor, generiert jedoch Werte, die nicht in der richtigen Reihenfolge vorliegen, sodass sie neu angeordnet werden müssen. Was auf jeder Ebene passiert, ist, dass jeder vorherigen Werteliste der neue Wert am Ende und am Anfang hinzugefügt wird und diese jeweils in ein 2-Tupel eingeschlossen werden, die in einer Liste zusammengefasst sind. Im ersten Schritt wird beispielsweise Folgendes ausgeführt:

[[1]]
[([1,2], [2,1])]

Dann wird diese Liste von Tupeln gezippt (und dann summiert, um die äußerste Liste zu entfernen). Im ersten Fall wird nur der nicht umbrochene Wert von oben angegeben, da die Liste nur einen Wert enthält.

Schritte mit 2-> 3:

([1,2], [2,1])
[([1,2,3],[3,1,2]),([2,1,3],[3,2,1])]
([1,2,3],[2,1,3],[3,1,2],[3,2,1])
FryAmTheEggman
quelle
2

Mathematica, 57 54 49 Bytes

f@1={{1}};f@n_:=#@n/@f[n-1]&/@Append~Join~Prepend

Beispiel:

f[4]

{{1, 2, 3, 4}, {2, 1, 3, 4}, {3, 1, 2, 4}, {3, 2, 1, 4}, {4, 1, 2, 3} , {4, 2, 1, 3}, {4, 3, 1, 2}, {4, 3, 2, 1}}

Alephalpha
quelle
2

J, 26 Bytes

   0|:<:((,,.,~)1+#)@[&0,.@1:

   (0|:<:((,,.,~)1+#)@[&0,.@1:) 3
1 2 3
2 1 3
3 1 2
3 2 1

1-Byte-Verbesserung dank FUZxxl .

randomra
quelle
Ersatz ,.für ,"1für ein Zeichen.
FUZxxl
1

Pyth, 34 33 31 29

Im Grunde eine Übersetzung von xnor ‚s Python Antwort . Ich bin immer noch nicht so gut mit Pyth, daher sind Verbesserungsvorschläge willkommen.

Definiert eine Funktion yzum Zurückgeben einer Liste mit ganzen Zahlen.

L?]]1<b2smm++*kdb*k_dy-b1,1_1

Update: 2 Bytes dank FryAmTheEggman gespeichert .

Erläuterung:

L                                  define a function y with argument b that returns
 ?*]]1<b2                          [[1]] if b < 2 else
         s                         sum(
          m                        map(lambda d:
           m                       map(lambda k:
            ++*kdb*k_d             k*d + [b] + k*-d
                      y-b1         , y(b - 1))
                          ,1_1)    , (1, -1))
PurkkaKoodari
quelle
Einige Pyth-Sachen: -b1können sein tb, [1_1)können sein ,1_1(Sie können jedoch einfach die schließende Klammer fallen lassen, da Sie nur die zur Ausführung der Funktion erforderlichen Bytes zählen müssen, auch wenn Sie sie nicht aufrufen können, ohne sie zu schließen), und Sie Es muss nicht bin eine Liste eingeschlossen werden, da Pyth beim Hinzufügen einer Liste zu einem Int automatisch in eine Liste konvertiert wird.
FryAmTheEggman
Ich hatte eine Möglichkeit, mehrere Bytes zu sparen, indem ich die zweite Map manuell überarbeitete [1,-1]. Ich kann Bytes speichern, um etwas so Kurzes fest zu codieren, besonders wenn Sie die Logik vereinfachen. Ich bekommeL?]]1<b2sCm,+db+bdytb
FryAmTheEggman
@FryAmTheEggman Vielleicht möchten Sie das als Ihre eigene Antwort hinzufügen. Das ist einfach großartig.
PurkkaKoodari
OK, ich wollte versuchen, CJam vor dem Posten zu schlagen, aber ich denke, der Zip-Trick ist interessant genug, um das Posten zu verdienen. Viel Glück mit Pyth;)
FryAmTheEggman
1

Pure Bash, 103

Länger als ich gehofft hatte:

a=1..1
for i in {2..9} {a..u};{
((++c<$1))||break
a={${a// /,}}
a=`eval echo $a$i $i$a`
}
echo ${a%%.*}
Digitales Trauma
quelle
1

JavaScript (ES6) 73 80

JavaScript-Implementierung der netten Lösung von @ Optimizer.

Rekursiv (73):

R=(n,i=1,r=[[1]])=>++i>n?r:r.map(e=>r.push([i,...e])+e.push(i))&&R(n,i,r)

Iterativ (74):

F=n=>(i=>{for(r=[[1]];++i<=n;)r.map(e=>r.push([i,...e])+e.push(i))})(1)||r

Test In der Firefox / FireBug-Konsole

R(4)

[[1, 2, 3, 4], [2, 1, 3, 4], [3, 1, 2, 4], [3, 2, 1, 4], [4, 1, 2, 3] , [4, 2, 1, 3], [4, 3, 1, 2], [4, 3, 2, 1]]

edc65
quelle
0

Meine Java-Lösung:

public static void main(String[] args) {
    listPrependAppend(4);
}

private static void listPrependAppend(int n) {
    int total = (int) Math.pow(2, n - 1);
    int ps;
    boolean append;
    String sequence;
    String pattern;

    for (int num = 0; num < total; num++) {
        sequence = "";
        pattern = "";
        append = false;
        ps = num;
        for (int pos = 1; pos < n + 1; pos++) {
            sequence = append ? (pos + sequence) : (sequence + pos);
            append = (ps & 0x01) == 0x01;
            ps = ps >> 1;
            if (pos < n) {
                pattern += append ? "L" : "R";
            }
        }
        System.out.format("%s\t[%s]%n", sequence, pattern);
    }
}
Brett Ryan
quelle
Oh fark, jetzt, nachdem ich die anderen Antworten gesehen habe, verstehe ich, was du mit der kürzesten Antwort meinst.
Brett Ryan
2
Obwohl Ihre Lösung an sich seriös, präzise und gut präsentiert ist, haben Sie Recht, dass sie für das vorliegende Problem nicht ganz in Frage kommt.
Joe Z.
1
@BrettRyan Sie können Ihren Code viel kürzer machen, indem Sie unnötige Leerzeichen entfernen und Variablennamen mit einem Zeichen verwenden. Sie können auch falsedurch etwas ersetzen 5<4.
ProgramFOX
1
Danke Leute. Es war mein erster Versuch, an Code-Herausforderungen teilzunehmen. Ich war nur auf der Suche nach einigen Programmierherausforderungen und wusste nicht, dass das Ziel darin bestand, die kürzeste Lösung zu finden. :) Danke, dass du mich teilnehmen lässt.
Brett Ryan