El reto
Es bastante simple en realidad, ordenar una lista de números.
Detalles
Debe ordenar una lista de números en orden ascendente, sin utilizar ninguna función de clasificación / bibliotecas / etc (es decir, list.sort()
en Python).
La entrada / salida se puede hacer en cualquier método que elija, siempre que sea legible por humanos.
Las lagunas estándar no se permiten como siempre.
El código más corto en bytes gana.
Debe explicar / enumerar qué método de clasificación utilizó (burbuja, inserción, selección, etc.)
La entrada no contendrá duplicados.
Muestra de entrada / salida
Entrada: 99,-2,53,4,67,55,23,43,88,-22,36,45
Salida: -22,-2,4,23,36,43,45,53,55,67,88,99
Nota: Un opuesto casi directo de Ordenar una lista de números
[7 2 4 1] -> [4 2 3 1]
. Además, ¿puede la lista CSV estar entre paréntesis? Además, el formato de entrada específico es muy adecuado para algunos idiomas y malo para otros. Esto hace que el análisis de entrada sea una gran parte para algunos envíos e innecesario para otros.Respuestas:
05AB1E , 2 bytes
Código:
Mismo algoritmo que la respuesta Jelly . Calcula todas las permutaciones de la entrada y saca la más pequeña.
Pruébalo en línea!
Un método más eficiente es:
Realiza la selección de clasificación . Utiliza CP-1252 codificación .
Pruébalo en línea!
fuente
Jalea, 3 bytes
Esto genera todas las permutaciones de la lista de entrada, luego selecciona la permutación lexográficamente más pequeña. Muy eficiente
Créditos a @Adnan que tuvo la misma idea de forma independiente.
Pruébalo en línea!
Jalea, 4 bytes
Esto construye el rango desde el mínimo de la lista hasta el máximo de la lista, luego descarta los elementos del rango que no están presentes en la lista original. Esto es técnicamente un tipo de cubo , con cubos muy pequeños. No conozco un nombre para esta variante específica.
Pruébalo en línea!
Cómo funciona
fuente
Python,
4645 bytesTipo de selección simple.
fuente
l[:]
podría ser1*l
Brachylog ,
127 bytesEsto usa el tipo de permutación, que obviamente es terrible, pero bueno, ¡es más corto que Pyth!
Explicación
fuente
Haskell, 38 bytes
La función binaria
%
inserta un nuevo elementoh
en una lista ordenadat
mediante la particiónt
en un prefijoa
de elementos<h
y un sufijob
de elementos>h
, y se pega enh
entre ellos.La operacion
foldr(%)[]
Luego, la construye una lista ordenada desde vacía insertando repetidamente elementos de la lista de entrada.Este es un byte más corto que la implementación recursiva directa
Otra estrategia para 41 bytes:
fuente
%
el bucle interno de inserción yfoldr
para aplicarlo como el bucle externo.JavaScript (ES6), 51 bytes
Cada ciclo encuentra el número más pequeño que no se ha encontrado hasta ahora.
fuente
[1,2,3,4,5,4,3,2,1]
produce[1, 2, 3, 4, 5, Infinity, Infinity, Infinity, Infinity]
Python 2, 34 bytes
Toma la entrada como un conjunto, imprime sus elementos en orden creciente y termina con un error.
Una terminación limpia se puede hacer en 41 bytes:
o
La entrada se puede tomar como una lista de 39 bytes o 38 bytes en Python 3.5:
fuente
m=min(s)
/s - (m)
como el bucle interno para encontrar y eliminar el mínimo de los elementos no clasificados, y la recursión como el externo.Haskell,
424138 bytesRecorre todos los enteros (firmado 64 bits, en mi máquina) y mantiene los que están en
u
. Por supuesto que no termina en un tiempo razonable.La versión anterior recorrió
[minimum u..maximum u]
que tiene el mismo tiempo de ejecución peor caso.Editar: @xnor guardó un byte. ¡Gracias!
fuente
filter
es uno más corto:f u=filter(`elem`u)[minimum u..maximum u]
[minimum u..]
No funciona por razones de tipo?f [1,3,0]
, los elementos predeterminan el tipoInteger
que no está vinculado, por lo que..
nunca termina. Si tiene que llamarlo asíf ([1, 3, 0]::[Int])
, supongo que la anotación de tipo debe incluirse en el recuento de bytes.Oracle SQL 11.2, 205 bytes
Sin golf
En cuanto a qué tipo de método es, no tengo idea,
ORDER BY
me aseguré de olvidarlos.fuente
Código de máquina x86-16 (BubbleSort int8_t),
2019 bytesCódigo de máquina x86-64 / 32 (JumpDownSort)
2119 bytesRegistro de cambios:
Gracias a @ ped7g por el
lodsb
/cmp [si],al
idea , y poner eso junto con un incremento / reinicio del puntero que había estado mirando. No necesitaral
/ah
nos permite usar casi el mismo código para enteros más grandes.Nuevo algoritmo (pero relacionado), muchos cambios de implementación: Bubbly SelectionSort permite una implementación x86-64 más pequeña para bytes o palabras clave; punto de equilibrio en x86-16 (bytes o palabras). También evita el error en size = 1 que tiene mi BubbleSort. Vea abajo.
Resulta que mi selección de selección burbujeante con intercambios cada vez que encuentras un nuevo min ya es un algoritmo conocido, JumpDown Sort. Se menciona en Bubble Sort: An Archaeological Algorithmic Analysis (es decir, cómo Bubble Sort se hizo popular a pesar de la succión).
Ordena enteros con signo de 8 bits en el lugar . (Sin signo es el mismo tamaño de código, simplemente cambie el
jge
ajae
). Los duplicados no son un problema. Intercambiamos usando una rotación de 16 bits por 8 (con un destino de memoria).Bubble Sort es una mierda para el rendimiento , pero he leído que es uno de los más pequeños para implementar en código máquina. Esto parece especialmente cierto cuando hay trucos especiales para intercambiar elementos adyacentes. Esta es prácticamente su única ventaja, pero a veces (en sistemas integrados de la vida real) es suficiente ventaja para usarla en listas muy cortas.
Omití la terminación anticipada de permutas . Utilicé el bucle BubbleSort "optimizado" de Wikipedia que evita mirar los últimos
n − 1
elementos cuando se ejecuta porn
enésima vez, por lo que el contador del bucle externo es el límite superior del bucle interno.Listado NASM (
nasm -l /dev/stdout
) o fuente simplepush / pop de
cx
alrededor del bucle interno significa que se ejecuta concx
= external_cx hasta 0.Tenga en cuenta que
rol r/m16, imm8
no es una instrucción 8086, se agregó más tarde (186 o 286), pero esto no está tratando de ser un código 8086, solo x86 de 16 bits. Si SSE4.1phminposuw
ayudara, lo usaría.Una versión de 32 bits de esto (todavía opera en enteros de 8 bits pero con punteros / contadores de 32 bits) es de 20 bytes (prefijo de tamaño de operando en
rol word [esi-1], 8
)Error: size = 1 se trata como size = 65536, porque nada nos impide ingresar al do / while externo con cx = 0. (Normalmente lo usaría
jcxz
para eso). Pero afortunadamente, el JumpDown Sort de 19 bytes tiene 19 bytes y no tiene ese problema.Versión original x86-16 de 20 bytes (sin la idea de Ped7g). Omitido para ahorrar espacio, vea el historial de edición con una descripción.
Actuación
El almacenamiento / recarga parcialmente superpuestos (en rotación de destino de memoria) provoca un bloqueo de reenvío de almacenamiento en CPU modernas x86 (excepto Atom en orden). Cuando un valor alto está burbujeando hacia arriba, esta latencia adicional es parte de una cadena de dependencia transportada en bucle. Almacenar / recargar apesta en primer lugar (como latencia de reenvío de 5 ciclos en Haswell), pero una pérdida de reenvío lo lleva a más de 13 ciclos. La ejecución fuera de orden tendrá problemas para ocultar esto.
Ver también: Desbordamiento de pila: clasificación de burbujas para ordenar cadenas para una versión de esto con una implementación similar, pero con una salida anticipada cuando no se necesitan intercambios. Utiliza
xchg al, ah
/mov [si], ax
para el intercambio, que es 1 byte más largo y provoca un bloqueo de registro parcial en algunas CPU. (Pero aún puede ser mejor que la memoria dst rotar, que necesita cargar el valor nuevamente). Mi comentario allí tiene algunas sugerencias ...Ordenación JumpDown x86-64 / x86-32, 19 bytes (ordena int32_t)
Se puede llamar desde C usando la convención de llamadas del sistema V x86-64 como
int bubblyselectionsort_int32(int dummy, int *array, int dummy, unsigned long size);
(valor de retorno = max (array [])).Esto es https://en.wikipedia.org/wiki/Selection_sort , pero en lugar de recordar la posición del elemento min, intercambie el candidato actual en la matriz . Una vez que haya encontrado el min (unsorted_region), guárdelo hasta el final de la región ordenada, como Ordenar por selección normal. Esto aumenta la región ordenada por uno. (En el código,
rsi
apunta a una pasada el final de la región ordenada;lodsd
avanza ymov [rsi-4], eax
almacena el min de nuevo en él).El nombre Jump Down Sort se usa en Bubble Sort: An Archaeological Algorithmic Analysis . Supongo que mi tipo es realmente un tipo Jump Up, porque los elementos altos saltan hacia arriba, dejando el fondo ordenado, no el final.
Este diseño de intercambio lleva a que la parte no ordenada de la matriz termine en su mayoría en orden inverso, lo que lleva a muchos intercambios más adelante. (Debido a que comienza con un candidato grande, y sigue viendo candidatos cada vez más bajos, por lo que sigue intercambiando). Lo llamé "burbujeante" a pesar de que mueve elementos en la otra dirección. La forma en que mueve los elementos también es un poco como una clasificación de inserción hacia atrás. Para verlo en acción, use GDB's
display (int[12])buf
, establezca un punto de interrupción en laloop
instrucción interna y usec
(continuar). Presione volver para repetir. (El comando "display" hace que GDB imprima todo el estado de la matriz cada vez que alcanzamos el punto de interrupción).xchg
with mem tiene unlock
prefijo implícito que hace que esto sea más lento. Probablemente un orden de magnitud más lento que un intercambio eficiente de carga / almacenamiento;xchg m,r
es uno por rendimiento de 23c en Skylake, pero cargar / almacenar / mover con un tmp reg para un intercambio eficiente (reg, mem) puede cambiar un elemento por reloj. Podría ser una relación peor en una CPU AMD donde elloop
instrucción es rápida y no obstaculizaría tanto el bucle interno, pero las fallas de ramificación seguirán siendo un gran cuello de botella porque los intercambios son comunes (y se vuelven más comunes a medida que la región no clasificada se vuelve más pequeña) )El tamaño del código mismo para
int8_t
: usolodsb
/scasb
,AL
y el cambio de la[rsi/rdi-4]
a-1
. El mismo código de máquina funciona en modo de 32 bits para elementos de 8/32 bits. El modo de 16 bits para elementos de 8/16 bits debe reconstruirse con los desplazamientos modificados (y los modos de direccionamiento de 16 bits usan una codificación diferente). Pero aún así 19 bytes para todos.Evita la inicial
dec ecx
al comparar con el elemento que acaba de cargar antes de continuar. En la última iteración del bucle externo, carga el último elemento, comprueba si es menor que sí mismo, y luego está listo. Esto le permite trabajar con size = 1, donde mi BubbleSort falla (lo trata como size = 65536).Probé esta versión (en GDB) usando esta llamada: ¡ Pruébelo en línea! . Puede ejecutarlo en TIO, pero por supuesto no hay depurador ni impresión. Aún así, el
_start
que lo llama sale con estado de salida = elemento más grande = 99, por lo que puede ver que funciona.fuente
cx
y usoloop
para ambos? ¿Quizás hacer un bucle al revés, de atrás hacia adelante de la matriz para que podamos contar un índice hasta cero? (E incrementebx
porque la parte ordenada está al final hacia la que se dirige).sub si, cx
como parte del bucle externo usar un puntero en lugar de indexar, pero no había pensado enlodsb
/cmp [si], al
. Había estado considerandolodsw
/dec si
, olodsb
/xchg al,ah
todavía configurar paracmp ah,al
cld
, o supongo que podríamos hacer esa parte de la convención de llamadas. AFAIK, haberloDF
borrado no es una parte estándar de las convenciones de llamadas de 16 bits, solo 32/64. ¿O es solo que no puedes asumirlo en un gestor de arranque? Pero con una convención de llamada de registro personalizada, este es un fragmento de código tanto como una función, así que, por qué no requiere DF = 0. (Y si queremos, ES = DS para poderscasb
hacerlo en lugar de hacerlolodsb
si fuera más conveniente.)C, 72 bytes
Ordenamiento de burbuja. El primer argumento es un puntero a la matriz, el segundo argumento es la longitud de la matriz. Funciona con gcc.
fuente
MATL ,
1110 bytesExamen extremadamente ineficiente de todas las permutaciones de la entrada.
Pruébalo en línea!
Explicación
fuente
Rubí, 40 bytes.
Selección de selección. Función anónima; toma la lista como argumento.
fuente
Python, 120 bytes
Probablemente esta no sea la respuesta más corta, pero siento que este algoritmo pertenece aquí. llame con una lista de enteros, se imprimirán de manera ordenada para stdout. Sin embargo, no lo intentaría con números demasiado grandes.
fuente
MIPS, 68 bytes
Hace un tiempo escribí una implementación simple de burbuja no optimizada. El recuento de bytes comienza en
loop
y termina enli $v0, 10
, suponiendo que la dirección y la longitud de la lista ya estén en la memoria.Ahora espero ser expulsado del agua con x86 ...
fuente
swapped=true
verificación anticipada y la cuenta regresiva según el tamaño de la matriz. Vea mi versión de 20 bytes x86-16 que ordena enteros de 8 bits . Podría hacer una versión x86 normal de 32 o 64 bits que clasifique enteros de 32 bits en algún momento, pero los enteros de 8 bits en modo de 16 bits son una especie de punto ideal para x86.Awk, 66 bytes
Las matrices en awk son como diccionarios, no como matrices en C. Los índices pueden ser no contiguos y crecen (y se crean) según sea necesario. Entonces, creamos una matriz
a
para la entrada, con cada línea como clave. Y guardamos los valores mínimo y máximo. Luego recorremos de min a max e imprimimos todas las claves que existen ena
.b
es solo para evitar el uso repetido de$0
.fuente
Python 3,
916247 bytesGracias a wnnmaw y Seeq por su ayuda en el golf.
El argumento
z
debería ser una lista. Esta es una variante del tipo de selección.No estoy seguro de cómo se
min
comparabuilt-in sorting functions
, ya que no estoy seguro de cómo se implementa Pythonmin
. Con suerte, esta solución aún está bien. Cualquier sugerencia de golf en los comentarios o en el chat PPCG es bienvenida.fuente
def f(z):\nwhile z:m=min(z);z.remove(m);yield m
MATL , 11 bytes
Pruébalo en línea!
Esto se ordena mediante el siguiente procedimiento, que es O ( n 2 ):
MATL está basado en pila. La matriz con los valores restantes se mantiene en la parte superior de la pila. Los valores eliminados están debajo, en orden. Al final del programa se muestran todos esos valores. La matriz en la parte superior también se mostrará, pero como está vacía, no se muestra.
fuente
Pyth -
15131110 bytesDos bytes guardados gracias a @Jakube.
Bogosort.
Pruébelo en línea aquí .
No necesito el
h
primo porque estamos garantizados sin duplicados.fuente
En serio, 6 bytes
Pruébalo en línea!
Esto hace lo mismo que muchas otras respuestas: generar todas las permutaciones, seleccionar mínimo. Olvidé un poco que esto funcionaría mientras estaba trabajando en la solución a continuación.
Explicación:
En serio, 25 bytes (no competitivos)
Esto sería competitivo si no fuera por un error en el comando shuffle que acabo de solucionar.
Pruébalo en línea! Esto implementa el mejor algoritmo de clasificación de todos los tiempos: Bogosort !
Explicación:
fuente
MATL
1716 bytesSe guardó un byte creando una matriz nula gracias a @LuisMendo
Tipo de cubo. No lo intentes con un rango mayor a 2 31 -1.
Pruébalo en línea!
Explicación
TIL:
[]
y crecerla, al igual que en MATLAB(
para indexar tareasM
portapapeles automáticoNuevo día, nuevo TIL:
vertcat
crea mágicamente una matriz vacía cuando no hay nada en la pila para concatenarfuente
[]
puede ser reemplazada porv
. Esto se debe a que la cantidad predeterminada de entradas dev
es la cantidad de elementos en la pilavertcat(STACK{:})
Julia,
2827 bytesPruébalo en línea!
fuente
R, 68 bytes
Toma entradas
i
y salidas,o
que es la lista ordenada.Explicación:
Evitar las permutaciones significa que puede ordenar listas grandes con relativa rapidez. El "truco" es que restar el valor más pequeño de la entrada deja un solo 0 que determina tanto el valor más pequeño como la posición del valor más pequeño.
fuente
Java 8,
11292 bytesAquí hay otro tipo de selección. La entrada es un número
List t
entero y la salida ordenada se imprime en salida estándar.Actualizar
fuente
t
que existe una variable , lo que lo convierte en un fragmento; requerimos que las presentaciones sean programas o funciones completos que utilizan nuestros formatos de E / S predeterminados . También exigimos que las importaciones tengan en cuenta el recuento de bytes. ¡Hazme saber si tienes alguna pregunta!Retina, 95
Tipo de burbuja modificado. Sospecho que hay formas mucho mejores de hacer esto, incluso sin el tipo de retina incorporado.
n
el dígito; deja caer las-
señales1
el dígito; agregue1
a cada uno, de modo que cero esté representado por1
.Pruébalo en línea.
fuente
Ruby, 22 bytes
Un tipo de permutación rápida . Se ejecuta en O (n!) Espacio y tiempo.
fuente
Clojure,
7335 bytesBogosort :)
Version anterior:
Se reduce a una lista ordenada
r
dividiéndola en partes "más pequeñas que i" y "más grandes que i". Supongo que este es el tipo de inserción .fuente
recur
en una función anónima. Tampoco lo sabíashuffle
.Ruby,
2624 bytesTipo de selección, similar a la respuesta de Value Ink, pero utilizando un enfoque diferente para una mayor golfidad.
De acuerdo con la especificación: "La entrada / salida se puede hacer en cualquier método que elija, siempre que sea legible por humanos". Creo que esto se ajusta a la descripción, la salida es una matriz de matrices con un solo elemento.
ejemplo:
fuente
Java 7,
106104bytesAquí hay un buen tipo de burbuja ole. El parámetro de función se modifica en su lugar para que no tenga que devolver nada. Todavía trato de exprimir algunos bytes de esto para poder vencer a la lambda de Java que alguien publicó.
-1 byte gracias a Geobits por señalar que el intercambio normal supera xor'ing
-1 byte gracias a Leaky Nun por señalar que puedo mover todas las declaraciones int al bucle for
Pruébalo en línea!
fuente
Ruby, 22 bytes
Crea una matriz fuera del rango entre los elementos mínimo y máximo de la matriz de entrada. Devuelve la intersección entre las dos matrices.
fuente