Salida de números ordinales (1º, 2º, 3º)


43

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?


Hola, NickC, y bienvenido a codegolf.SE! Solo para aclarar, ¿quiere decir que deberíamos leer un número 11como entrada y salida, por ejemplo 11th? ¿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?
Ilmari Karonen

1
¿Estás buscando el algoritmo más pequeño o el código más pequeño?
Toto

@Ilmari Estoy buscando 11como entrada y 11thcomo salida. No me importa si procesa varias líneas, pero lo que tenía en mente era procesar solo un número.
Nicole

@ M42 Sabes, no estoy muy seguro. No tengo un requisito estricto, pero probablemente estaba pensando en el algoritmo más pequeño.
Nicole

Respuestas:


30

Perl, 37 + 1 caracteres

s/1?\d\b/$&.((0,st,nd,rd)[$&]||th)/eg

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 el pinterruptor de línea de comando, de esta manera:

perl -pe 's/1?\d\b/$&.((0,st,nd,rd)[$&]||th)/eg'

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 pinterruptor cuenta como un carácter adicional .

Entrada de muestra:

This is the 1 line of the sample input...
...and this is the 2.
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
101 102 103 104 105 106 107 108 109 110

Salida:

This is the 1st line of the sample input...
...and this is the 2nd.
1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th
101st 102nd 103rd 104th 105th 106th 107th 108th 109th 110th

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.14159convierte 3rd.14159th.

¿Como funciona?

  • Primero, este es un reemplazo global de expresiones regulares ( s///g). La expresión regular que se coincide es 1?\d\b, donde \dcoincide con cualquier dígito y \bes 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\bcoincide con el último dígito de cualquier número, más el dígito anterior si resulta ser 1.

  • En la sustitución, que se evalúa como código Perl debido al /ecambio, 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 por th.


Editar: si la entrada está restringida a un solo entero, entonces esta solución de 35 caracteres será suficiente:

s/1?\d$/$&.((0,st,nd,rd)[$&]||th)/e

1
Debería poder dejar la gsustitució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.
Sr. Llama

@GigaWatt: De hecho, escribí el código antes de que NickC respondiera a mi pregunta sobre el formato de entrada, así que lo hice lo más genérico posible.
Ilmari Karonen

38

Python 2, 49 bytes

lambda n:`n`+'tsnrhtdd'[n%5*(n%100^15>4>n%10)::4]

Una función anónima. Un programa completo se contabilizaría en 55 bytes.

'tsnrhtdd'[i::4]codifica los sufijos th st nd rdpara los valores de i0 a 3. En vista de esto, todo lo que necesitamos es una manera de asignar los valores de nal índice del sufijo correspondiente i. 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 que n%5da los mismos resultados que n%10para los valores de ncon los sufijos especiales. Con un poco de ensayo y error, también se puede acortar 10<n%100<14a n%100^15>4, que puede ser encadenado con el otro condicional para ahorrar aún más bytes.


3
esto es algo de magia negra aquí c:
gato


No lo entiendo ¿Alguien puede explicar lo que está pasando aquí?
Pavel

@Pavel He actualizado mi respuesta con una explicación.
xsot

¡Increíble! Una forma brillante de pensar ...
Benison Sam

10

Python, 68 caracteres

i=input()
k=i%10
print"%d%s"%(i,"tsnrhtdd"[(i/10%10!=1)*(k<4)*k::4])

44
Esto es realmente tarde, pero puedes quitar 7 bytes haciendo `i`+"tsnrhtdd". De lo contrario, esta es la solución exacta que acabo de recibir.
DLosc

10

Mathematica 39 45 bytes

Nota: En versiones recientes de Mathematica, la solicitud de la nthparte de p, donde pno está definida, genera un mensaje de error, pero de todos modos devuelve la respuesta correcta. He agregado Quietpara evitar que se imprima el mensaje de error.

Quiet@StringSplit[SpokenString[p[[#]]]][[2]]&

Uso

Quiet@StringSplit[SpokenString[p[[#]]]][[2]] &[31]

31

Quiet@StringSplit[SpokenString[p[[#]]]][[2]] &/@Range[21]

{"1 °", "2 °", "3 °", "4 °", "5 °", "6 °", "7 °", "8 °", "9 °", "10 °", "11 °", "12 °", " 13 "," 14 "," 15 "," 16 "," 17 "," 18 "," 19 "," 20 "," 21 ""}


Cómo funciona

SpokenStringescribe una expresión válida de Mathematica como se podría decir. A continuación hay dos ejemplos de la documentación de SpokenString ,

SpokenString[Sqrt[x/(y + z)]]

"raíz cuadrada de la cantidad x sobre la cantidad y más z" *)

SpokenString[Graphics3D[Sphere[{{0, 0, 0}, {1, 1, 1}}]], "DetailedGraphics" -> True]

"un gráfico tridimensional que consta de esferas unitarias centradas en 0, 0, 0 y 1, 1, 1"


Ahora, para el ejemplo en cuestión,

Quiet@SpokenString[p[[#]]] &[31]

"el elemento 31 de p"

Representemos la cadena anterior como una lista de palabras:

StringSplit[%]

{"the", "31st", "element", "of", "p"}

y toma el segundo elemento ...

%[[2]]

31


Estoy confundido; donde se pdefine EDITAR: no importa, veo cómo estás usando esto; desafortunadamente no funciona en mi sistema. : - /
Mr.Wizard

Funciona en v.9.0.1. (Me parece recordar que está utilizando 7.0.) Sí, no es necesario definir p.
DavidC

Entiendo eso ahora. Sin embargo, en v7 obtengo de SpokenString @ p[[117]]la salida " part 117 of p".
Mr.Wizard

Entonces SpokenStringse 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.
DavidC

Ja, no había visto esa respuesta antes.
Mr.Wizard

7

Rubí, 60

No es tan bueno como la entrada de Perl, pero pensé que trabajaría en mis habilidades con Ruby.

def o(n)n.to_s+%w{th st nd rd}[n/10%10==1||n%10>3?0:n%10]end

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.


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.
hammar

Ok, lanzó en otro %10para compensar. Se agregaron 3 caracteres. (Siento que %10parece suficiente donde debería acortarse de alguna manera, pero no puedo pensar en una solución)
Sr. Llama

Nunca se puede vencer a Perl en la escritura de código incomprensible horrible que de tan corto como sea posible :)
jamylak

Establecer una variable a 10?
wizzwizz4

Creo que configurar una variable n%10es mejor.
CalculatorFeline

6

Javascript (ES6) 50 44 Bytes (no competitivos)

a=>a+=[,"st","nd","rd"][a.match`1?.$`]||"th"

Notas

  • toma la entrada como una cuerda
  • Eliminado 6 bytes, gracias @ user81655

1
a+-> a+=, eliminar paréntesis, \d-> ., eliminar [0], y si toma el número como una cadena: en a.match`1?.$`lugar de /1?.$/.exec(a).
user81655

Probablemente debería agregar un aviso de que esta respuesta no es competitiva, ya que ES6 no existía cuando se publicó el desafío.
user2428118

5

Javascript, 68 71

function o(n){return n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')}

Esfuerzo conjunto con ItsCosmo.

EDITAR: no funcionaba correctamente con números> 100


Puede 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')
reducirlo

@WallyWest Por alguna razón, me gusta mucho que mi solución funcione en navegadores modernos. Siéntase libre de publicar su propia respuesta; Creo que es lo suficientemente diferente.
aebabis

¡No, esta bien! ¡Solo proporciono algunas alternativas!
WallyWest

3

Golfscript, 34 caracteres

~.10/10%1=!1$10%*.4<*'thstndrd'2/=

3

Haskell, 95 caracteres

h=foldr g"th".show
g '1'"th"="1st"
g '2'"th"="2nd"
g '3'"th"="3rd"
g '1'[x,_,_]='1':x:"th"
g a s=a:s

Pruebas:

*Main> map h [1..40]
["1st","2nd","3rd","4th","5th","6th","7th","8th","9th","10th","11th","12th","13t
h","14th","15th","16th","17th","18th","19th","20th","21st","22nd","23rd","24th",
"25th","26th","27th","28th","29th","30th","31st","32nd","33rd","34th","35th","36
th","37th","38th","39th","40th"]

Debe cargarse con -XNoMonomorphismRestriction.


3

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 ^ 1evalúa a 0 para cualquier nfinal positivo con dígitos 08- 15. Por lo tanto, para cualquier n mod 100finalización en 11, 12o 13, la búsqueda de matriz regresa undefined, lo que lleva a un sufijo de th.

Para cualquier positivo nfinal en otros dígitos que 08- 15la expresión n % 100 >> 3 ^ 1evalúa a un número entero positivo, invocando la expresión n % 10de matriz de búsqueda, volviendo st, ndo rdpara nque termina con 1, 2o 3. De lo contrario, th.


Guardar un bytes con n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Shaggy

@ Shaggy, gracias, actualizado como se sugiere.
Tomas Langkaas


@ guest271314, es divertido ver cómo se usa este código. Tenga en cuenta que solo funciona para números positivos, otra alternativa es n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", adaptada de esta publicación .
Tomas Langkaas

3

APL (Dyalog Unicode) , 38 36 bytes

Gracias 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 a 0, que es predeterminado en muchos sistemas. Incluso funciona para 0!

⍕,{2'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}

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)

 multiplicar dos por que (da 0, 2, 4, o 6)

'thstndrd'↓⍨soltar tantos caracteres de esta cadena

2↑ toma los dos primeros personajes restantes

⍕, concatenar el argumento en cadena a ese


"31"
ngn

⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
ngn

lo siento, olvidé mencionarlo ⎕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 ...
ngn

@ngn Fijo. ¡Y también funciona para 0!
Adám

2

PowerShell, 92

process{"$_$(switch -r($_){"(?<!1)1$"{'st'}"(?<!1)2$"{'nd'}"(?<!1)3$"{'rd'}default{'th'}})"}

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.


2

J - 44 char

¿Nada en J? ¡Esto es un atropello!

(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])

Explicado (tenga en cuenta que 1es boolean verdadero en J y 0es 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 de 4>](es decir, si el dígito es o no menor que 4) y lo multiplica por el resultado de tens ~: (4>]). ¿Por qué alguien haría esto? Considera lo siguiente:
    • Si estamos verificando 10, 11, 12, 13, entonces tenses 1(estamos en la adolescencia) y oneses menor que 4, entonces tens ~: (4>])es falso y el resultado es 0*1= 0.
    • Si somos cualquier otro de {X0, X1, X2, X3}, entonces tens ~: (4>])es claramente cierto y salimos 1*1= 1.
    • Si oneses mayor que cuatro, entonces 4>]fue 0y no importa lo que pase con la prueba, saldremos 0independientemente.
    • Para resumir, [(~:*])4>]es 1si estamos en {X0, X1, X2, X3} pero no en la adolescencia, y de lo 0contrario.
  • ]*- Finalmente multiplicamos ese resultado por el dígito de las unidades. Por lo tanto, este producto será 0si 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. 0consigue 'th', 1consigue '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.

   (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 112         NB. single use
112th
   (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 1 2 3 4 5   NB. doing it wrong
|length error
|       (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])1 2 3 4 5
   NB. i.5 10   makes a 5x10 grid of increasing integers
   NB. &.>      to operate on each integer separately, and box the result after
   (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])&.> i.5 10   NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+

2

C #, 62 bytes

n=>n+(n/10%10==1||(n%=10)<1||n>3?"th":n<2?"st":n<3?"nd":"rd");

Programa completo y verificación:

using System;

namespace OutputOrdinalNumbers
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int,string>f= n=>n+(n/10%10==1||(n%=10)<1||n>3?"th":n<2?"st":n<3?"nd":"rd");

            for (int i=1; i<=124; i++)
                Console.WriteLine(f(i));
        }
    }
}

Puede jugar golf por dos bytes cambiando el ||a |.
Kevin Cruijssen

2

Mathematica 29 + 5 = 34 bytes

SpokenStringDump`SpeakOrdinal

+5 bytes porque se Speakdebe llamar a la función antes de usar este incorporado.

Uso

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

Sé que este programa no es comparable a los demás. Simplemente tenía ganas de dar una solución.

<?$s=explode(' ',trim(fgets(STDIN)));foreach($s as$n){echo$n;echo(int)(($n%100)/10)==1?'th':($n%10==1?'st':($n%10==2?'nd':($n%10==3?'rd':'th')))."\n";}

puede guardar algunos caracteres usandoforeach($s as $n){echo$n;
karthik

1

Scala 86

def x(n:Int)=n+{if(n%100/10==1)"th"else(("thstndrd"+"th"*6).sliding(2,2).toSeq(n%10))}

Scala 102:

def x(n:Int)=if((n%100)/10==1)n+"th"else if(n%10<4)n+("thstndrd".take(n+1)%5*2.drop(n%5*2))else n+"th"

102 también:

def x(n:Int)=if((n%100)/10==1)n+"th"else if(n%10<4)n+("thstndrd".sliding(2,2).toSeq(n%10))else n+"th"

sin golf:

def x (n: Int) =
  n + { if (((n % 100) / 10) == 1) "th" 
        else (("thstndrd"  + ("th"  * 6)).sliding (2, 2).toSeq (n % 10))
      }

1

OCaml

Soy bastante nuevo en OCaml, pero esto es lo más corto que pude conseguir.

let n x =
   let v = x mod 100 and string_v = string_of_int x in
   let z = v mod 10 in
   if v=11 || v=12 || v=13 then string_v^"th" 
   else if v = 1 || z = 1 then string_v^"st" else if v = 2 || z = 2 then string_v^"nd" else if v = 3 || z = 3 then string_v^"rd" else string_v^"th";;

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.


input: 11 produciría output:

Sí, tienes razón ... He hecho la corrección. Gracias
Joseph Elcid

Acabo de ordenar el formato de su código. Cada línea debe estar precedida por cuatro espacios para ser reconocida como un bloque de código.
Gareth

¿No sería tu primero si el cheque fuera más corto if v>10 && v<14? No estoy familiarizado con ocaml, pero ¿es necesario que la string_vvariable sea tan larga?
Gaffi

No, no es necesario, podría haber elegido w o x. Solo quería algo significativo. Pero tienes razón, habría hecho el código un poco más corto.
Joseph Elcid

1

K - 44 char

Sucede que esto es exactamente tan largo como el J, y funciona casi de la misma manera.

{x,$`th`st`nd`rd@{y*(y<4)*~1=x}.-2#0,.:'x$:}

Explicado:

  • x$:- Primero, convertimos el operando xen una cadena, y luego lo asignamos nuevamente a x. 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 argumentos xy ypara esta función interna, que devuelve ysi yes menor que 4 y xno 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:

  {x,$`th`st`nd`rd@{y*(y<4)*~1=x}.-2#0,.:'x$:} 3021
"3021st"
  {x,$`th`st`nd`rd@{y*(y<4)*~1=x}.-2#0,.:'x$:}' 1 2 3 4 11 12 13 14  /for each in list
("1st"
 "2nd"
 "3rd"
 "4th"
 "11th"
 "12th"
 "13th"
 "14th")

1

C - 95 83 caracteres

main(n,k){scanf("%d",&n);k=(n+9)%10;printf("%d%s\n",n,k<3?"st\0nd\0rd"+3*k:"th");}

Degolfed:

main(n,k)
{
    scanf("%d",&n);
    k=(n+9)%10; // xx1->0, xx2->1, xx3->2
    printf("%d%s\n",n,k<3?"st\0nd\0rd"+3*k:"th");
}

Podríamos hacerlo en k=(n-1)%10lugar de sumar 9, pero para n = 0 obtendríamos un comportamiento incorrecto, porque en C se (-1)%10evalúa a -1, no a 9.


1

Javascript, 75

function s(i){return i+'thstndrd'.substr(~~(i/10%10)-1&&i%10<4?i%10*2:0,2)}

1

PHP, 98 bytes

function c($n){$c=$n%100;$s=['','st','nd','rd'];echo$c>9&&$c<14||!$s[$c%10]?$n.'th':$n.$s[$c%10];}

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

function c($n){$c=abs($n%100);$s=['','st','nd','rd'];echo$c>9&&$c<14||!$s[$c%10]?$n.'th':$n.$s[$c%10];}

1

Python, 88 84 bytes

lambda x:x+((('th','st','nd','rd')+('th',)*6)[int(x[-1])]if('0'+x)[-2]!='1'else'th')

Sin golf:

def y(x):
    return x + (('th', 'st', 'nd', 'rd') + ('th', ) * 6)[int(x[-1])] if ('0' + x)[-2] != '1' else 'th')

lambda xdefine una función anónima con parámetro x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]define una tupla de las terminaciones para números menores que 10, el 0-thelemento es para 0, y así sucesivamente. los if ('0'+x)[-2] != '1'comprueba si existe 11, 12o un 13a solución, y se suma a continuación, else 'th'añade then lugar de st, rdo nd.


Esta es una gran respuesta, pero me llevó un tiempo entenderla. Si pudiera agregar una explicación y un desglose del código debajo de la versión de golf de su código, ayudaría a las personas a aprender de su código y mejorar la calidad de su respuesta.
wizzwizz4

Esta bien lo hare. ¿Debo agregar también una respuesta sin golf?
NoOneIsHere

No debería ser una respuesta diferente ... Lo que has hecho está bien, bien hecho. Si quieres más desafíos, podría darte algunas recomendaciones.
wizzwizz4

Okay. Podrías intentar ... ajustar tu silla o dónde se sentarán tus amigos . O podrías probar algunos de mis desafíos , como The Knight's Next Tour . Si estos no son el tipo de desafíos que te gustan, solo dilo.
wizzwizz4

1

JavaScript (Node.js) , 51 bytes

crédito a @KevinCruijssen por mejorar la respuesta

n=>n+=[,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th'

Pruébalo en línea!


Explicacion:

n =>                      // input
    n+=[,'st','nd','rd']     // the array of suffices add everything to n
        [~~(n/10%10)-1?n%10:0] // the full magic 
    || 'th'               // works for everything except 1 , 2 , 3 just like what you want


1

R , 79 76 bytes

Como 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)].

function(x)paste0(x,c("th","st","nd","rd",rep("th",6))[1+x%%10*!x%%100==11])

Pruébalo en línea!

Con substr79 bytes:

function(x,y=1+2*min(x%%10-(x%%100==11),4))paste0(x,substr("thstndrdth",y,y+1))

Pruébalo en línea!


1
1+x%%10*!x%%100==11para el índice?
Giuseppe

@Giuseppe Necesito calmarme entre paréntesis :). Uso inteligente de !delante de la expresión en lugar de !=.
JayCe

1
Sí, los operadores tienen precedencia extraña; ^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.
Giuseppe

0

Python 2.7, 137 caracteres

def b(n):
 for e,o in[[i,'th']for i in['11','12','13']+list('4567890')]+[['2','nd'],['1','st'],['3','rd']]:
  if n.endswith(e):return n+o

n debería ser una cuerda

Sé 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 ey el ordinal o. 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 positivo


n[-1]==ees 5 caracteres más corto quen.endswith(e)
hlt

0

C: 95 caracteres

Una solución ridículamente larga:

n;main(){scanf("%d",&n);printf("%d%s",n,n/10%10-1&&(n=n%10)<4&&n?n>2?"rd":n<2?"st":"nd":"th");}

Necesita ser destrozado más.


Un usuario marcó este dicho "es incorrecto: no se repite en absoluto, es decir, funciona solo para un número determinado, no para todos los números debajo de él. Consulte ideone.com/pO6UwV". Esa no es una razón para marcar, ya que los moderadores no juzgan la corrección, pero puede ser un problema.
dmckee

Basado en este comentario del creador de la pregunta: "@Ilmari estoy buscando 11 como entrada y 11 como salida. No me importa si procesa varias líneas, pero lo que tenía en mente era procesar solo un número. - NickC Jan 20'12 a las 21:00 "está haciendo lo que debería. Es decir, solo debe procesar un solo número.
Fors

lo siento por esa bandera; Leí mal el requisito, y no tenía suficiente representante en ese momento, para comentar directamente. Lo siento de nuevo. :)
Will Ness

0

Javascript, 75

function o(s){return s+((0|s/10%10)==1?"th":[,"st","nd","rd"][s%10]||"th")}

0

Oracle SQL 11.2, 101 bytes

SELECT:1||DECODE(ROUND(MOD(:1,100),-1),10,'th',DECODE(MOD(:1,10),1,'st',2,'nd',3,'rd','th'))FROM DUAL

0

Javascript ES6, 52 caracteres

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.