Me gustaría generar (como resultado de una función, o simplemente como la salida de un programa) el sufijo ordinal de un entero positivo concatenado con el número.
Muestras:
1st
2nd
3rd
4th
...
11th
12th
13th
...
20th
21st
22nd
23rd
24th
Y así sucesivamente, con el sufijo repitiendo el subpatrón inicial 1-10 cada 10 hasta 100, donde el patrón finalmente comienza de nuevo.
La entrada sería el número y la salida la cadena ordinal como se muestra arriba.
¿Cuál es el algoritmo más pequeño para esto?
11
como entrada y salida, por ejemplo11th
? ¿Está cada número en la entrada en una línea separada, y los números de salida deben estar en líneas separadas también? ¿Y necesitamos manejar más de una línea de entrada?11
como entrada y11th
como salida. No me importa si procesa varias líneas, pero lo que tenía en mente era procesar solo un número.Respuestas:
Perl, 37 + 1 caracteres
Esta es una sustitución regexp que agrega el sufijo ordinal apropiado a cualquier número
$_
que ya no esté seguido de una letra. Para aplicarlo a la entrada de archivo, use elp
interruptor de línea de comando, de esta manera:Este es un programa completo de Perl que lee la entrada de stdin y escribe la salida procesada en stdout. El código real tiene 37 caracteres, pero el
p
interruptor cuenta como un carácter adicional .Entrada de muestra:
Salida:
Los números ya seguidos por letras serán ignorados, por lo que alimentar la salida nuevamente a través del filtro no lo cambiará. Los espacios, las comas y los puntos entre los números no se tratan especialmente, por lo que se supone que separan los números como cualquier otro signo de puntuación. Por lo tanto, por ejemplo, se
3.14159
convierte3rd.14159th
.¿Como funciona?
Primero, este es un reemplazo global de expresiones regulares (
s///g
). La expresión regular que se coincide es1?\d\b
, donde\d
coincide con cualquier dígito y\b
es una aserción de ancho cero que coincide con el límite entre un carácter alfanumérico y un carácter no alfanumérico. Por lo tanto,1?\d\b
coincide con el último dígito de cualquier número, más el dígito anterior si resulta ser1
.En la sustitución, que se evalúa como código Perl debido al
/e
cambio, tomamos el segmento de cadena coincidente ($&
) y le agregamos (.
) el sufijo obtenido al usarlo$&
como un índice entero en la lista(0,st,nd,rd)
; si este sufijo es cero o no está definido (es decir, cuando$&
es cero o mayor que tres), el||
operador lo reemplaza porth
.Editar: si la entrada está restringida a un solo entero, entonces esta solución de 35 caracteres será suficiente:
fuente
g
sustitución si especifica que cada número debe estar en su propia línea. Además, eso le permitiría cambiar el límite de la palabra para que sea$
. Pero en general, +1, maldita solución inteligente.Python 2, 49 bytes
Una función anónima. Un programa completo se contabilizaría en 55 bytes.
'tsnrhtdd'[i::4]
codifica los sufijosth st nd rd
para los valores dei
0 a 3. En vista de esto, todo lo que necesitamos es una manera de asignar los valores den
al índice del sufijo correspondientei
. Una expresión directa que funciona es(n%10)*(n%10<4 and 10<n%100<14)
. Podemos acortar fácilmente esto eliminando el primer conjunto de paréntesis y observando quen%5
da los mismos resultados quen%10
para los valores den
con los sufijos especiales. Con un poco de ensayo y error, también se puede acortar10<n%100<14
an%100^15>4
, que puede ser encadenado con el otro condicional para ahorrar aún más bytes.fuente
Python, 68 caracteres
fuente
`i`+"tsnrhtdd"
. De lo contrario, esta es la solución exacta que acabo de recibir.Mathematica
3945 bytesNota: En versiones recientes de Mathematica, la solicitud de la
nth
parte dep
, dondep
no está definida, genera un mensaje de error, pero de todos modos devuelve la respuesta correcta. He agregadoQuiet
para evitar que se imprima el mensaje de error.Uso
Cómo funciona
SpokenString
escribe una expresión válida de Mathematica como se podría decir. A continuación hay dos ejemplos de la documentación de SpokenString ,Ahora, para el ejemplo en cuestión,
Representemos la cadena anterior como una lista de palabras:
y toma el segundo elemento ...
fuente
p
define EDITAR: no importa, veo cómo estás usando esto; desafortunadamente no funciona en mi sistema. : - /SpokenString @ p[[117]]
la salida" part 117 of p"
.SpokenString
se revisa de vez en cuando. No me sorprendería que este código ( codegolf.stackexchange.com/questions/8859/… ) tampoco funcione en el v. 7. Por cierto, no estaba destinado a ser una solución duradera.Rubí, 60
No es tan bueno como la entrada de Perl, pero pensé que trabajaría en mis habilidades con Ruby.
La función toma un argumento entero
n
, y devuelve una cadena como la forma ordinal.Funciona de acuerdo con la siguiente lógica:
si el dígito de las decenas es un 1 o el dígito de las unidades es mayor que 3, use el sufijo 'th'; de lo contrario, encuentre el sufijo de la matriz ['th', 'st', 'nd', 'rd'] utilizando el último dígito como índice.
fuente
o(113)
es"113rd"
, debería ser"113th"
. El cheque de diez dígitos no tiene en cuenta los números con más de dos dígitos.%10
para compensar. Se agregaron 3 caracteres. (Siento que%10
parece suficiente donde debería acortarse de alguna manera, pero no puedo pensar en una solución)10
?n%10
es mejor.Javascript (ES6)
5044 Bytes (no competitivos)Notas
fuente
a+
->a+=
, eliminar paréntesis,\d
->.
, eliminar[0]
, y si toma el número como una cadena: ena.match`1?.$`
lugar de/1?.$/.exec(a)
.Javascript,
6871Esfuerzo conjunto con ItsCosmo.
EDITAR: no funcionaba correctamente con números> 100
fuente
function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
Golfscript, 34 caracteres
fuente
Haskell, 95 caracteres
Pruebas:
Debe cargarse con -XNoMonomorphismRestriction.
fuente
JavaScript, 64 caracteres (ES3) o 47 caracteres (ES6)
ES3 (64 caracteres):
function(n){return n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'}
ES6 (47 caracteres):
n=>n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'
Explicación
La expresión se
n % 100 >> 3 ^ 1
evalúa a 0 para cualquiern
final positivo con dígitos08
-15
. Por lo tanto, para cualquiern mod 100
finalización en11
,12
o13
, la búsqueda de matriz regresaundefined
, lo que lleva a un sufijo deth
.Para cualquier positivo
n
final en otros dígitos que08
-15
la expresiónn % 100 >> 3 ^ 1
evalúa a un número entero positivo, invocando la expresiónn % 10
de matriz de búsqueda, volviendost
,nd
ord
paran
que termina con1
,2
o3
. De lo contrario,th
.fuente
n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'
.n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th"
, adaptada de esta publicación .APL (Dyalog Unicode) ,
3836 bytesGracias a ngn por corregir un error mientras se mantiene el conteo de bytes.
Función de prefijo tácito anónimo. Requiere
⎕IO
( I ndex O rigin) conjunto a0
, que es predeterminado en muchos sistemas. Incluso funciona para 0!Pruébalo en línea!
{
...}
lambda anónimo;⍵
es argumento:⍳4
primeros cuatro Ɩ ndices;[0,1,2,3]
10↑
tome los primeros diez elementos de eso, rellenando con ceros:[0,1,2,3,0,0,0,0,0,0]
⊂
adjuntar para tratar como elemento único;[[0,1,2,3,0,0,0,0,0,0]]
1 0 8\
expandir a una copia, una copia prototípica (todo cero), ocho copias;[[0,1,2,3,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,1,2,3,0,0,0,0,0,0],
[0,1,2,3,0,0,0,0,0,0],
⋮ (5 más)
[0,1,2,3,0,0,0,0,0,0]]
∊
ϵ nlist (aplanar);[0,1,2,3,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,1,2,3,0,0,0,0,0,0,
0,1,2,3,0,0,0,0,0,0,
⋮ (50 más)
0,1,2,3,0,0,0,0,0,0]
⍵⌽
gire cíclicamente a la izquierda tantos pasos como lo indique el argumento⊃
elige el primer número (es decir, el número de argumento-mod-100)2×
multiplicar dos por que (da0
,2
,4
, o6
)'thstndrd'↓⍨
soltar tantos caracteres de esta cadena2↑
toma los dos primeros personajes restantes⍕,
concatenar el argumento en cadena a esefuente
⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
⎕io←0
. Puedo ver que lo has adivinado, pero hay algunos 1,2,3,4,0,0 ... que deberían ser 0,1,2,3,0,0 ...PowerShell, 92
Funciona con un número por línea de entrada. La entrada se da a través de la tubería. Hacer que funcione para un solo número no reduce el tamaño.
fuente
J - 44 char
¿Nada en J? ¡Esto es un atropello!
Explicado (tenga en cuenta que
1
es boolean verdadero en J y0
es falso):10 10(...)/@#:]
- Primero tomamos el argumento (]
) y encontramos las decenas y unos dígitos (10 10 #:
). Luego, insertaremos(...)
entre los dos.(]*[(~:*])4>])
- En esta subexpresión, pero no la más interna,]
apuntará al dígito de las unidades y[
al dígito de las decenas.[(~:*])4>]
-~:
es J para "no iguales", por lo que toma el resultado de4>]
(es decir, si el dígito es o no menor que 4) y lo multiplica por el resultado detens ~: (4>])
. ¿Por qué alguien haría esto? Considera lo siguiente:tens
es1
(estamos en la adolescencia) yones
es menor que 4, entoncestens ~: (4>])
es falso y el resultado es0*1
=0
.tens ~: (4>])
es claramente cierto y salimos1*1
=1
.ones
es mayor que cuatro, entonces4>]
fue0
y no importa lo que pase con la prueba, saldremos0
independientemente.[(~:*])4>]
es1
si estamos en {X0, X1, X2, X3} pero no en la adolescencia, y de lo0
contrario.]*
- Finalmente multiplicamos ese resultado por el dígito de las unidades. Por lo tanto, este producto será0
si el número merece un'th'
sufijo, de lo contrario, su valor.th`st`nd`rd{::~
- Utilizamos los dígitos modificados de arriba para indexar la lista de sufijos.0
consigue'th'
,1
consigue'st'
, etc.":,
- Finalmente, tome el número original, conviértalo en una cadena (":
), y luego añádalo al sufijo.El uso es obvio, aunque tal como está el verbo solo puede tomar un ordinal, no una lista.
fuente
C #, 62 bytes
Programa completo y verificación:
fuente
||
a|
.Mathematica 29 + 5 = 34 bytes
+5 bytes porque se
Speak
debe llamar a la función antes de usar este incorporado.Uso
fuente
PHP, 151
Sé que este programa no es comparable a los demás. Simplemente tenía ganas de dar una solución.
fuente
foreach($s as $n){echo$n;
Scala 86
Scala 102:
102 también:
sin golf:
fuente
OCaml
Soy bastante nuevo en OCaml, pero esto es lo más corto que pude conseguir.
Creé una función n que toma un número como parámetro y hace el trabajo. Es largo, pero pensé que sería genial tener un ejemplo funcional.
fuente
if v>10 && v<14
? No estoy familiarizado con ocaml, pero ¿es necesario que lastring_v
variable sea tan larga?K - 44 char
Sucede que esto es exactamente tan largo como el J, y funciona casi de la misma manera.
Explicado:
x$:
- Primero, convertimos el operandox
en una cadena, y luego lo asignamos nuevamente ax
. Necesitaremos su representante de cadena nuevamente más tarde, por lo que al hacerlo ahora se guardan los caracteres..:'
- Convierta (.:
) cada ('
) dígito nuevamente en un número.-2#0,
- Agregue un 0 al principio de la lista de dígitos (en el caso de números de un solo dígito), y luego tome los dos últimos.{y*(y<4)*~1=x}.
- Utilice los dos dígitos como argumentosx
yy
para esta función interna, que devuelvey
siy
es menor que 4 yx
no es igual a 1, de lo contrario 0.`th`st`nd`rd@
- Indice la lista de sufijos por este resultado.x,$
- Convierta el sufijo de símbolo a cadena y agréguelo al número original.Uso:
fuente
C -
9583 caracteresDegolfed:
Podríamos hacerlo en
k=(n-1)%10
lugar de sumar 9, pero para n = 0 obtendríamos un comportamiento incorrecto, porque en C se(-1)%10
evalúa a -1, no a 9.fuente
Javascript, 75
fuente
PHP, 98 bytes
El bit 11-13 me está matando aquí. Funciona para cualquier número entero
$n >= 0
.Para cualquier número entero
$n
:PHP, 103 bytes
fuente
Python,
8884 bytesSin golf:
lambda x
define una función anónima con parámetrox
.((('th','st','nd','rd')+('th',)*6)[int(x[-1])]
define una tupla de las terminaciones para números menores que 10, el0-th
elemento es para0
, y así sucesivamente. losif ('0'+x)[-2] != '1'
comprueba si existe11
,12
o un13
a solución, y se suma a continuación,else 'th'
añadeth
en lugar dest
,rd
ond
.fuente
JavaScript (Node.js) , 51 bytes
crédito a @KevinCruijssen por mejorar la respuesta
Pruébalo en línea!
Explicacion:
fuente
R ,
7976 bytesComo todavía no hay una solución R ... no hay trucos aquí, indexación vectorial básica, bajó 3 caracteres gracias a Giuseppe. Índice previamente probado:
[1+(x%%10)-(x%%100==11)]
y[1+(x%%10)*(x%%100!=11)]
.Pruébalo en línea!
Con
substr
79 bytes:Pruébalo en línea!
fuente
1+x%%10*!x%%100==11
para el índice?!
delante de la expresión en lugar de!=
.^
es muy alto, entonces%%
los operadores de tipo, entonces*/
y+-
y creo==
y&|
que viene a continuación.!
tiene una precedencia bastante baja, por lo que puede usarlo como separador entre operaciones.Python 2.7, 137 caracteres
n
debería ser una cuerdaSé que ya estoy derrotado por la competencia aquí, pero pensé que daría mi idea de todos modos
esto básicamente genera una lista de pares clave, valor con número (como una cadena) final
e
y el ordinalo
. Intenta hacer coincidir 'th' primero (por eso no utilicé un diccionario), para que no vuelva accidentalmente a 'st', por ejemplo, cuando debería ser 'th'. Esto funcionará para cualquier entero positivofuente
n[-1]==e
es 5 caracteres más corto quen.endswith(e)
C: 95 caracteres
Una solución ridículamente larga:
Necesita ser destrozado más.
fuente
Javascript, 75
fuente
Oracle SQL 11.2, 101 bytes
fuente
Javascript ES6, 52 caracteres
fuente