Construir un permuter

9

Para este desafío, hará una función (su función puede ser un programa completo) que toma una lista como entrada y devuelve una permutación de esa lista. Su función debe obedecer los siguientes requisitos.

  • Debe ser determinista.

  • Al componer su función consigo mismo un número variable de veces debería ser capaz de obtener una lista de cualquiera de sus permutaciones.

Esta es una pregunta de código de golf, por lo que las respuestas se puntuarán en bytes, con menos bytes mejor.

Reglas adicionales

  • Usted puede tomar cualquier tipo de lista, ( [Integer], [String], [[Integer]]), siempre y cuando

    • Puede estar no vacío
    • Puede contener objetos distintos con al menos 16 valores posibles. (No puede usar un Haskell [()]y afirmar que su función es id)
    • Puede contener objetos duplicados (sin conjuntos)
  • Puede escribir un programa o una función, pero debe obedecer el estándar IO.

Ad Hoc Garf Hunter
fuente
Pero S_nes solo cíclico paran<3
Leaky Nun
@LeakyNun, no está pidiendo una sola permutación que genere el grupo simétrico: está pidiendo una next_permutationfunción.
Peter Taylor
¿Sería suficiente permutar las listas de 0 y 1?
xnor
No estoy seguro de entender el punto de esta restricción. Si permite listas de booleanos, ¿cuál es el punto de no permitir iterables sobre dos elementos distintos?
Dennis
@ Dennis Haces un buen punto. No permitiré listas de booleanos. O tipos que tienen menos de 16 valores posibles.
Ad Hoc Garf Hunter

Respuestas:

4

CJam (11 bytes)

{_e!_@a#(=}

Demostración en línea que muestra el ciclo completo de una lista de cuatro elementos con un elemento duplicado.

Disección

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

Mathematica + Combinatorica (paquete incorporado) 34 bytes

19 bytes para cargar el paquete y 15 para la función.

<<"Combinatorica`";NextPermutation

Uso:

%@{c, b, a}

Sin el incorporado, 61 Bytes

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

Se supone que Combinatorica está completamente incorporada en Mathematica, pero creo que se pasó por alto la función NextPermutation.

Kelly Lowder
fuente
2

C ++, 42 bytes

#include <algorithm>
std::next_permutation

Esta operación exacta está integrada en C ++.

orlp
fuente
2
¿Por qué el espacio después #include?
Yytsi
2

JavaScript (ES6), 145 139 137 134 108 bytes

¡Ahorré la friolera de 25 bytes gracias a @Neil!

Toma la entrada como una matriz de caracteres alfabéticos. Devuelve la siguiente permutación como otra matriz.

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

¿Cómo?

Esta es una generación en orden lexicográfico que procesa los 4 pasos siguientes en cada iteración:

  1. Encuentre el índice X más grande tal que a [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. Encuentre el índice más grande Y mayor que X tal que a [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. Cambie el valor de una [X] con el de una [Y]

    a[x] = a[y], a[y] = t
  4. Ordenar la secuencia desde un [X + 1] hasta el elemento final incluido, en orden lexicográfico ascendente

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

Ejemplo:

pasos

Manifestación

Arnauld
fuente
¿No puedes ordenar en lugar de invertir? También creo que v<a[i+1]&&(t=v,x=i)ahorra un byte, y es posible que pueda ahorrar más usando splicedos en lugar de dos slice.
Neil
@Neil Buena captura!
Arnauld
Creo que pude fusionar los dos maps también, para 112 bytes: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
Tengo que admitir que no pensé que a.concat(a.splice(++x).sort())iba a funcionar, de lo contrario lo habría intentado ...
Neil
@Neil ¡Gracias! Actualizado. (Con 4 bytes más guardados porque realmente no necesitamos t para concat () ).
Arnauld
1

Jalea , 6 bytes

Œ¿’œ?Ṣ

Recorre las permutaciones en orden lexicográfico descendente.

Pruébalo en línea!

Cómo funciona

Œ¿’œ?Ṣ  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
fuente
1

C, 161 bytes

Algoritmo real de O (n).

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

Ejemplo de uso:

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

Pruébalo en línea!

Dennis
fuente
Creo que esto es más corto como una función que permuta la lista en el lugar.
orlp
Lo intenté, pero execme dio todo tipo de errores en una función
Dennis
0

Jalea , 10 bytes

ṢŒ!Q©i⁸‘ị®

Pruébalo en línea!

Ordenar> toda permutación> buscar entrada> agregar 1> índice en "toda permutación

Monja permeable
fuente
@PeterTaylor Lo he arreglado.
Leaky Nun
Hay incorporaciones específicas para permutaciones (es decir, simplemente puede hacer Œ¿‘œ?Ṣ). No tenía ganas de robar desde, bueno, lo mismo.
Erik the Outgolfer
@EriktheOutgolfer puede ser un poco complicado para las entradas que contienen duplicados.
Leaky Nun
Hmm ... supongo que sí, tenía una versión que funcionó para eso anteriormente, pero parece que usas la Qcosita. Todavía puedes jugar golf ṢŒ!Qµi³‘ị.
Erik the Outgolfer
0

PHP , 117 bytes

Toma entrada / salida como lista de cadenas de letras inferiores

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

Pruébalo en línea!

Jörg Hülsermann
fuente