Genere el conjunto de permutaciones de anteponer-agregar en orden lexicográfico

14

Defina una secuencia de longitud de anteponer-agregarn para que sea una permutación de los números 1, 2, ..., nque se pueden generar mediante el siguiente procedimiento:

  • Comience con el número 1.

  • Para cada número de 2a n, colocar este número al principio o al final de la secuencia (ya sea prepend o append , de ahí el nombre de la secuencia).

Por ejemplo, esta es una forma válida de generar una secuencia de anteponer-agregar de longitud 4:

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

Su tarea es crear un programa o función que tome un número nde 3a 30como entrada, e imprima o devuelva todas las secuencias de longitud de anteponer y agregar nen orden lexicográfico (si está generando cadenas y no listas, los números superiores a 9 se representarán como letras a-u, para preservar la longitud de la cadena). Por ejemplo, este es el orden para n = 4:

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

En general, hay 2 n-1 antemutaciones de longitud de anexión n.

No puede usar ninguna función de clasificación incorporada en su idioma en su código. El programa más corto para hacer esto en cualquier idioma gana.

Joe Z.
fuente
No soy fanático del requisito de formato de salida, en particular la conversión a letras a-u. ¿Podemos simplemente generar listas de números?
xnor
3
Es posible que desee aceptar la respuesta después de un tiempo, ya que algunas personas tienden a no responder una pregunta si tiene una respuesta aceptada.
Optimizador
1
Entonces has aceptado la respuesta incorrecta ..
Optimizer
2
FryAmTheEggman publicó su respuesta 21 minutos antes de que editara la suya.
Joe Z.
2
@Optimizer No creo que sea la forma más extraña: la respuesta de FryAmTheEggman fue de 19 bytes, 21 minutos antes que la suya. Eso lo convierte en la respuesta más corta publicada más temprano.
Joe Z.

Respuestas:

10

CJam, 22 20 19 17 bytes

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

Expansión de código :

]]                   "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";

Cómo funciona :

Esta es una versión de depuración del código:

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

Veamos cómo funciona para la entrada 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>|}/";

Pruébalo en línea aquí

Optimizador
fuente
6

Haskell, 47 bytes

f 1=[[1]]
f n=(\x->map(++[n])x++map(n:)x)$f$n-1
alephalpha
fuente
1
Cambiar a la comprensión de la lista ahorra algunos bytes: f n=[[n:x,x++[n]]|x<-f$n-1]>>=id(utilizando la función concat de golfistas de código >>=id).
nimi
1
@nimi pero está en el orden equivocado r
orgulloso haskeller
@proudhaskeller: Oh querido, no leí las especificaciones con suficiente cuidado. Traté de solucionarlo y encontré cuatro formas ligeramente diferentes, todas de la misma longitud que la versión de @ alephalpha, por lo que no puedo ofrecer una mejora. 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
Nombre del modelo
5

Pitón 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)]

Emite una lista de listas de números.

Una solución recursiva. Para n==1, salida [[1]]. De lo contrario, agregue nal inicio o al final de todas las (n-1)permutaciones. La preparación previa hace que la permutación sea lexicográfica más tarde que la adición, por lo que las permutaciones permanecen ordenadas.

El "booleano" bcodifica si se debe poner [n]al principio o al final. En realidad, movemos el resto de la lista xen la expresión x*b+[n]+x*-b. Poner bcomo -1o 1permite usar flip negando, ya que una lista multiplicada por -1es la lista vacía.

xnor
fuente
4

Pyth, 19

usCm,+dH+HdGr2hQ]]1

Pruébalo en línea aquí

Este es un programa completo que toma información de stdin.

Esto funciona de manera similar a la solución de xnor, pero genera los valores un poco fuera de orden, por lo que deben reordenarse. Lo que sucede en cada nivel es que cada lista de valores anterior tiene el nuevo valor agregado al final y al principio y cada uno está envuelto en una tupla de 2 que está envuelta en una lista. Por ejemplo, el primer paso hace esto:

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

Luego, esta lista de tuplas se comprime (y luego se suma para eliminar la lista más externa). En el primer caso, esto solo da el valor sin envolver de arriba, ya que solo hay un valor en la lista.

Pasos que muestran 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
fuente
2

Mathematica, 57 54 49 bytes

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

Ejemplo:

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
fuente
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

Mejora de 1 byte gracias a FUZxxl .

randomra
fuente
Sustituir ,.por ,"1un personaje.
FUZxxl
1

Pyth 34 33 31 29

Básicamente una traducción de la respuesta Python de xnor . Todavía no soy bueno con Pyth, así que las sugerencias de mejora son bienvenidas.

Define una función ypara devolver una lista de listas de enteros.

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

Actualización: Guardado 2 bytes gracias a FryAmTheEggman .

Explicación:

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
fuente
Algunas cosas de pyth: -b1puede ser tb, [1_1)puede ser ,1_1(sin embargo, solo puede soltar el corchete cerrado ya que solo necesita contar los bytes necesarios para realizar la función, aunque no podrá llamarlo sin cerrarlo), y usted no necesita bajustarse en una lista, ya que pyth se convierte automáticamente en lista cuando agrega una lista a un int.
FryAmTheEggman
Se me ocurrió una forma de guardar varios bytes haciendo manualmente el segundo mapa [1,-1]. Puedo guardar bytes para codificar algo tan corto, especialmente cuando simplifica la lógica. Me saleL?]]1<b2sCm,+db+bdytb
FryAmTheEggman
@FryAmTheEggman Es posible que desee agregar eso como su propia respuesta. Eso es simplemente asombroso.
PurkkaKoodari
OK, quería intentar vencer a CJam antes de publicar, pero supongo que el truco zip es lo suficientemente interesante como para merecer publicarlo. Buena suerte con Pyth;)
FryAmTheEggman
1

Pure Bash, 103

Más de lo que esperaba:

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

JavaScript (ES6) 73 80

Implementación de JavaScript de la buena solución de @ Optimizer.

Recursivo (73):

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

Iterativo (74):

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

Prueba en la consola Firefox / FireBug

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
fuente
0

Mi solución Java:

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
fuente
Oh fark, ahora después de ver las otras respuestas veo lo que quieres decir con la respuesta más corta.
Brett Ryan
2
Si bien su solución es respetable, concisa y bien presentada por derecho propio, tiene razón en que no es una buena candidata para el problema en cuestión.
Joe Z.
1
@BrettRyan Puede hacer que su código sea mucho más corto eliminando espacios en blanco innecesarios y utilizando nombres de variables de un carácter. También puede reemplazar falsepor algo como 5<4.
ProgramFOX
1
Gracias chicos. Fue mi primer intento de participar en desafíos de código. Estaba buscando algunos desafíos de programación y no me di cuenta de que el objetivo era obtener la solución más corta. :) Gracias por dejarme participar.
Brett Ryan