Alfabetizar enteros

19

Alfabetizar enteros

Para un conjunto dado de números, póngalos en orden alfabético cuando se deletreen (es decir, 1: uno, 2: dos, 90: noventa, 19: diecinueve). Su código debería funcionar para el rango [-999999, 999999]. La salida debe tener un delimitador entre números. Un espacio funcionará, al igual que un espacio y una coma como se muestra en los ejemplos a continuación. La entrada puede ser una matriz de enteros, una cadena de números delimitados, o como mejor le parezca. Se supone que todos los enteros son únicos.

Los números no están separados por guiones para los propósitos de este desafío y los espacios están ordenados alfabéticamente antes que cualquier otro personaje. Se supone que los números negativos se expresan usando la palabra minus. Por ejemplo, fourprecedería four thousandy el número se -40ordenaría usando la cadena minus forty. Suponga que todos los números estarán compuestos únicamente por palabras numéricas y sin conjunciones (por ejemplo, use en two thousand forty twolugar de two thousand and forty two).


Casos de prueba

Enteros de un solo dígito:

Entrada:

1, 2, 3, 4, 5

Salida:

5, 4, 1, 3, 2

Múltiples dígitos enteros:

Entrada:

-1002, 5, 435012, 4, 23, 81, 82

Salida:

81, 82, 5, 4, 435012, -1002, 23

Espacios entre palabras, sin guiones, comas o "y":

Entrada:

6, 16, 60, 64, 600, 6000, 60000, 60004, 60008, 60204, 60804

Salida:

6, 600, 6000, 16, 60, 64, 60000, 60008, 60804, 60004, 60204

Recuerde, este es el , por lo que gana el código con la menor cantidad de bytes. ¡No se permiten escapatorias!

wubs
fuente
Aquí está el enlace a la publicación de sandbox relevante.
wubs
¿La entrada contendrá alguna vez más de un entero entero?
ETHproductions
@ETHproductions No, no lo hará. Lo especificaré en la pregunta.
wubs
8
Bienvenido a PPCG. Bonito avatar. : D Bonita primera pregunta.
AdmBorkBork
@TimmyD ¡Gracias! Estoy deseando que PowerShell haga todo lo que pueda por aquí.
wubs

Respuestas:

5

JavaScript (ES6), 189 179 186 bytes

let f =

a=>a.sort((x,y)=>!x-!y||(X=q(x),Y=q(y),X>Y)-(X<Y),q=n=>n<0?"L"+q(-n):n>999?q(n/1e3)+"Z"+q(n%1e3):n>99?q(n/100)+"K"+q(n%100):n>19?"  cYHFVSCO"[n/10|0]+q(n%10):"0PdaIGTQAMWDbXJEURBN"[n|0])

let g = a => console.log(`[${f(a)}]`)

g([1,2,3,4,5])
g([-1002,5,435012,4,23,81,82])
g([0,1000,1100])
<input id=I value="1 2 3 4 5"><button onclick="g(I.value.match(/\d+/g)||[])">Run</button>

La idea básica es convertir cada número de entrada en una cadena corta que esté en la posición lexográfica correcta en comparación con todos los otros pares de cadenas de números. Aquí está el diccionario utilizado: (No ejecute el fragmento; solo se utiliza para ocultar la lista larga).

Esto crea una forma muy concisa de asignar cada número a su posición lexográficamente correcta. Eso es lo recursivoq función :

q(-X)        => "L" + q(X)
q(XYYY)      => q(X) + "Z" + q(YYY)
q(XYY)       => q(X) + "K" + q(YY)
q(XY >= 20)` => "  cYHFVSCO"[X] + q(Y)
q(X)         => "0PdaIGTQAMWDbXJEURBN"[X]

El 0principio de la cadena es asegurar que, por ejemplo, 100 ( one hundred, convertido a PK0) se ordene antes 101( one hundred one, convertido a PKP). Esto crea un escenario extraño donde 0 ( zero) se ordena al frente de la matriz, por lo tanto, para evitar esto, en la función de clasificación primero ordenamos los ceros a la derecha !x-!y||(....

ETHproducciones
fuente
Parece que no funciona [1100, 1000]. Esperaría que la salida fuera 1000 (one thousand), 1100 (one thousand one hundred), pero la salida es del mismo orden que la entrada.
leche
@milk Hmm ... No estoy seguro de por qué sucede esto, pero lo investigaré.
ETHproductions
@milk Ah, 1000se analiza como one thousand zero; Arreglaré esto momentáneamente. ¿Sin 0embargo, debemos apoyar por sí mismos? Es un caso único que agregará 15 bytes más o menos a mi código.
ETHproductions
11

Informar 7, 214 201 118 bytes

Inform 7 es un lenguaje absolutamente terrible para el golf, por lo que quería darle una oportunidad aquí.

La sangría debe usar caracteres tab ( \t), pero a HTML no le gustan. Por el contrario, a Inform no le gustan los espacios para sangría, por lo que deberá reemplazar los espacios con pestañas si copia y pega el código desde aquí para probarlo. O simplemente copie y pegue de la fuente Markdown en su lugar.

Golfizado:

A X:
    repita a través de la Tabla 1:
        ahora la entrada Q es "[Entrada R en palabras]";
    ordenar la Tabla 1 en orden Q;
    diga "[R en la Tabla 1]".

La entrada debe ser una tabla Inform, así (con \tentre las columnas):

tabla 1
R (número) Q (texto)
-1002
5 5
435012
4 4
23
81
82

Salida:

81, 82, 5, 4, 435012, -1002, 23

Esta función se ejecuta a través de la tabla una vez, agregando una representación textual de cada número en una nueva columna. Luego ordena las filas de la tabla de acuerdo con la columna de texto; en Inform, las cadenas se ordenan lexicográficamente. Finalmente, imprime la columna original en el nuevo orden. Convenientemente, el formato "crudo pero a veces útil" de Inform 7 para imprimir columnas de tablas resulta estar separado por comas, exactamente como se solicitó.

Ungolfed, con repetitivo que muestra cómo llamar a la función:

Para imprimir los números en orden alfabético:
    repita a través de la tabla de números ordenables:
        ahora la entrada del nombre es "[la entrada del índice en palabras]";
    ordenar la tabla de números ordenables en orden de nombre;
    diga "[la columna de índice en la Tabla de números ordenables]".

Tabla de números clasificables
índice (número) nombre (texto)
-1002
5 5
435012
4 4
23
81
82

Hay un cuarto.
Cuando comienza el juego: imprime los números en orden alfabético.
Draconis
fuente
1
Estoy un poco confundido por esto. ¿Se incluye wordsuna referencia de las versiones detalladas de los números en Inform 7?
Pavel
1
@Pavel hecho! "(número) en palabras" devuelve una cadena con una representación textual del número. Utiliza convenientemente "menos" para números negativos, y si bien coloca guiones entre las palabras, lo hace consistentemente y ordena alfabéticamente los guiones antes de todas las letras (por lo que el resultado final es el mismo).
Draconis
2
+1 para la elección del idioma. Tendría que comprobarlo, pero sospecho que aún quedan algunas oportunidades de golf; por ejemplo, ¿el analizador realmente requiere todos esos "los" artículos? Y tendría que preguntar al OP, pero no veo ninguna razón obvia por la cual "y" no sea un delimitador válido. Incluso si no, un solo espacio está explícitamente permitido, por lo que say "[R entry] "debería ser suficiente.
Ilmari Karonen
Yo diría que "y" al final está bien. No dije que los delimitadores tuvieran que ser uniformes, por lo que esta es una respuesta perfectamente aceptable. Si pudiera dar puntos por la respuesta más interesante, te lo daría. Realmente disfruto la legibilidad de este lenguaje, incluso el golf. ¡Buen trabajo!
wubs
Finalmente tuve la oportunidad de jugar un poco con Inform7, y logré re-golf tu entrada a solo 118 bytes. Dado que publicar el código Inform en los comentarios no funciona muy bien, seguí adelante y lo edité en su respuesta directamente. Espero que no te importe, siéntete libre de revertir y / o modificar mis ediciones de la manera que quieras.
Ilmari Karonen
4

Mathematica, 67 bytes

SortBy[#,#~IntegerName~"Words"~StringReplace~{","->"","-"->""}&]&

Función sin nombre que toma una lista de enteros como argumento y devuelve una lista de enteros como su valor. #~IntegerName~"Words"es una función integrada que cambia un número entero a su nombre en inglés. IntegerNamea veces tiene comas y guiones en su salida, por lo que la StringReplacellamada los elimina. (Lamentablemente, el guión es en realidad el carácter de 3 bytes, 8208, en UTF-8.) Luego SortByordena la lista original alfabéticamente según el valor del nombre entero modificado.

Una buena coincidencia: IntegerNameusa en negativelugar de minusen su salida, pero ninguna palabra que aparece en los nombres de ninguno de los números permitidos está alfabéticamente entre esas dos palabras, ¡por lo que no es necesario reemplazarla!

(Punta de sombrero para ngenisis por recordarme Sortby).

Greg Martin
fuente
¡Prestigio! Estuve muy cerca de obtener esta solución, ¡pero ese guión me estaba dando dolores de cabeza!
ngenisis
¿Su respuesta aquí realmente usa el guión correcto? Si copio lo que tienes aquí en Mathematica, no reemplaza los guiones de IntegerName. La documentación de Wolfram dice que es unicode character 2010 .
ngenisis
Probablemente no, entonces, intenté obtener el guión correcto en esta respuesta, pero parece que no tuve éxito.
Greg Martin
Corté tu respuesta a la mitad;)
J. Antonio Pérez
Y luego algo ... haces modificaciones innecesarias a la cadena.
J. Antonio Perez
4

Bash + GNU utils + bsdgames, 52

  • 4 bytes guardados gracias a @izabera.
sed 's/.*/echo `echo &|number`:&/e'|sort|sed s/.*://

I / O son líneas delimitadas por nueva línea.

  • La primera expresión sed reemplaza cada número numérico con un comando de shell que genera la forma de la palabra del número (como lo proporciona la utilidad bsdgamesnumber ), seguido de un: forma numérica del número.
  • Esto es entonces sorted.
  • Luego, el segundo sedelimina los caracteres principales hasta e incluyendo el :, dejando la forma numérica ordenada según sea necesario.

numbermaneja correctamente "menos", y su salida está lo suficientemente cerca del formato específico que sortfunciona como se requiere. Produce "cuarenta y cuatro" en lugar de "cuarenta y cuatro", pero esto no debería importar desde la perspectiva de la clasificación.

El paquete bsdgames puede necesitar instalación:

sudo apt-get install bsdgames

Las utilidades sedy sortcasi seguramente ya están en su distribución.

Trauma digital
fuente
-t:es inútil y puedes usarlonumber<<<&
izabera
@izabera Sí, gracias. Eliminé el -t:. Sin embargo, la efunción val de sed ejecuta comandos usando sh, por lo que las funciones bash como <<<no funcionarán.
Trauma digital
funciona bien siempre y cuando tu sh sea bash: P
izabera
@izabera Nope: si bash se inicia, ya shque trata de emular Posix sh tanto como sea posible, lo que significa que los bashismos como <<<están desactivados. sedLa efunción val de GNU inicia comandos con /bin/sh -c ...y no /bin/bash -c .... ¿Has probado esto?
Trauma digital
bash nunca se apaga <<<, ni siquiera en modo posix
izabera
1

Python + inflex, 97 91 89 bytes

from inflect import*
a={x:engine().number_to_words(x)for x in words}
sorted(a,key=a.get)

Usó la inflectbiblioteca para transformar la wordsmatriz de enteros en su representación fonética / de cadena. Almacenado en un diccionario de pares k / v donde las claves eran la representación numérica y los valores eran la representación de la cadena. Devuelve la lista de claves ordenadas por valores.

EDITAR: ¡Guardado 5 y 3 bytes, gracias a ETHproductions y Alex.S!

9814072356
fuente
Bienvenido a PPCG! Puedes jugar golf eliminando espacios ; por ejemplo, la segunda línea puede ser a={x:inflect.engine().number_to_words(x)for x in words}.
ETHproductions
Puede guardar dos bytes usando from inflect import*y tirando inflect.en la segunda línea.
Alex.S
Por desgracia, parece que esto tampoco logra ordenar correctamente la lista 40, 44, 40000, 40804, 40004, 40204 (que debe permanecer en ese orden).
Ilmari Karonen
0

Mathematica, 30 bytes

La siguiente respuesta genera una función pura que tomará una lista de enteros como entrada y los ordenará por su nombre alfabético. Justo lo que recetó el doctor ;)

SortBy[#~IntegerName~"Words"&]

Aquí está la versión sin golf:

SortBy[IntegerName[#, "Words"]&]

Y aquí hay un ejemplo de uso:

SortBy[#~IntegerName~"Words"&][{0,1,2,3,4,5,6,7,8,9,10}]

Que también podría escribirse como

SortBy[#~IntegerName~"Words"&]@{0,1,2,3,4,5,6,7,8,9,10}

Producen salidas idénticas - en matemática, f[x]es equivalente a f@x.

Outputs: {8, 5, 4, 9, 1, 7, 6, 10, 3, 2}

Hay una respuesta mucho más larga que otro usuario publicó en Mathematica. Esa respuesta trata de corregir algunas pequeñas diferencias entre la forma en que Mathica alfebatiza los números para ajustarse mejor a la forma en que los números indicados por OP deben alfebatizarse, sin embargo, las cosas que corrigen no afectan el orden de clasificación, y mi respuesta sale idénticamente a la suya:

MyF = SortBy[#~IntegerName~"Words"&];
TheirF = SortBy[#, #~IntegerName~"Words"~ StringReplace~{"," -> "", "-" -> ""} &] &;
MyF[Range[-999999, 999999]] == TheirF[Range[-999999, 999999]]
(*Outputs True*)
J. Antonio Perez
fuente
¡Una gran investigación! Desafortunadamente, en realidad no dan el mismo orden. TheirFordena correctamente 888 antes de 880,000, mientras queMyF que no lo hace. Probablemente el problema esté relacionado con el copiado y pegado del extraño guión: su versión de TheirFprobablemente está reemplazando los guiones normales (de los cuales no hay ninguno), mientras que la versión real reemplaza el extraño guión Unicode de 3 bytes. (Todavía sería interesante ver si es necesario eliminar comas).
Greg Martin
Lo probé en Range [999999]. Parece que eliminar las comas es innecesario, pero definitivamente es necesario reemplazar "[Hyphen]" con "".
ngenisis
0

Lisp común, 113 bytes

No se necesitan bibliotecas externas.

(print(mapcar #'cdr(sort(loop for i in x collect(cons(format()"~r"i)i))(lambda(y z)(string-lessp(car y)(car z))))))

Salida si xes '(1 2 3 4 5):

(5 4 1 3 2)
Harry
fuente