Saída de números ordinais (1º, 2º, 3º)


43

Gostaria de gerar (como resultado de retorno de uma função ou simplesmente como saída de um programa) o sufixo ordinal de um número inteiro positivo concatenado ao número.

Amostras:

1st  
2nd  
3rd  
4th  
...  
11th  
12th  
13th  
...  
20th  
21st
22nd
23rd
24th

E assim por diante, com o sufixo repetindo o subpadrão inicial de 1 a 10 a cada 10 até 100, onde o padrão finalmente começa novamente.

A entrada seria o número e a saída a sequência ordinal, como mostrado acima.

Qual é o menor algoritmo para isso?


Olá, NickC, e bem-vindo ao codegolf.SE! Apenas para esclarecer, você quer dizer que devemos ler um número como 11entrada e saída, por exemplo 11th? Cada número da entrada está em uma linha separada e os números de saída também devem estar em linhas separadas? E precisamos lidar com mais de uma linha de entrada?
Ilmari Karonen

1
Você está procurando o menor algoritmo ou o menor código?
Toto

@ Ilmari Estou procurando 11como entrada e 11thsaída. Não me importo se ele processa várias linhas, mas o que eu tinha em mente era processar apenas um único número.
Nicole

@ M42 Você sabe, não tenho muita certeza. Não tenho um requisito estrito - mas provavelmente estava pensando no menor algoritmo.
20912 Nicole

Respostas:


30

Perl, 37 + 1 caracteres

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

Esta é uma substituição regexp que acrescenta o sufixo ordinal apropriado a qualquer número $_que ainda não seja seguido por uma letra. Para aplicá-lo à entrada de arquivo, use a popção de linha de comando, assim:

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

Este é um programa Perl completo que lê a entrada do stdin e grava a saída processada no stdout. O código real tem 37 caracteres, mas o pswitch conta como um caractere extra .

Entrada de amostra:

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

Resultado:

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

Os números já seguidos de letras serão ignorados, portanto, alimentar a saída novamente pelo filtro não a alterará. Espaços, vírgulas e pontos entre números não são tratados de maneira especial; portanto, supõe-se que eles separem números como qualquer outra pontuação. Assim, por exemplo, 3.14159torna-se 3rd.14159th.

Como funciona?

  • Primeiro, essa é uma substituição global do regexp ( s///g). O regexp sendo correspondido é 1?\d\b, onde \dcorresponde a qualquer dígito e \bé uma asserção de largura zero que corresponde ao limite entre um caractere alfanumérico e não alfanumérico. Assim, 1?\d\bcorresponde ao último dígito de qualquer número, mais o dígito anterior, se for o caso 1.

  • Na substituição, que é avaliada como código Perl devido à /eopção, pegamos o segmento de string correspondente ( $&) e anexamos ( .) o sufixo obtido usando- $&se como um índice inteiro à lista (0,st,nd,rd); se esse sufixo for zero ou indefinido (ou seja, quando $&for zero ou maior que três), o ||operador o substituirá th.


Edit: Se a entrada for restrita a um único número inteiro, esta solução de 35 caracteres será suficiente:

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

1
Deverá poder gcancelar a substituição se você especificar que cada número deve estar em sua própria linha. Além disso, isso permitiria que você alterasse o limite da palavra $. Mas, em geral, +1, solução muito inteligente.
Llama

@GigaWatt: Na verdade, eu escrevi o código antes que o NickC respondesse à minha pergunta sobre o formato de entrada, então o tornei o mais genérico possível.
Ilmari Karonen

38

Python 2, 49 bytes

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

Uma função anônima. Um programa completo seria contado em 55 bytes.

'tsnrhtdd'[i::4]codifica os sufixos th st nd rdpara valores de i0 a 3. Dado isso, tudo o que precisamos é uma maneira de mapear os valores npara o índice do sufixo correspondente i,. Uma expressão direta que funciona é (n%10)*(n%10<4 and 10<n%100<14). Podemos encurtar isso facilmente, descartando o primeiro conjunto de parênteses e observando que n%5dá os mesmos resultados que n%10para os valores de ncom os sufixos especiais. Com um pouco de tentativa e erro, um também pode ser reduzido 10<n%100<14para n%100^15>4, que pode ser encadeado com o outro condicional para economizar ainda mais bytes.


3
esta é alguma magia negra bem aqui c:
cat


Eu não entendo. Alguém pode explicar o que está acontecendo aqui?
Pavel

@ Pavel Atualizei minha resposta com uma explicação.
Xsot # 28/16

Impressionante!
Maneira

10

Python, 68 caracteres

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

4
É realmente tarde, mas você pode tirar 7 bytes fazendo isso `i`+"tsnrhtdd". Caso contrário, esta é a solução exata que acabei de obter.
DLosc

10

Mathematica 39 45 bytes

Nota: Nas versões recentes do Mathematica, solicitar a nthparte de p, onde pé indefinida, gera uma mensagem de erro, mas retorna a resposta correta de qualquer maneira. Adicionei Quietpara impedir que a mensagem de erro seja impressa.

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 "}


Como funciona

SpokenStringgrava uma expressão válida do Mathematica conforme possa ser falada. Abaixo estão dois exemplos da documentação para SpokenString ,

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

"raiz quadrada da quantidade x sobre a quantidade y mais z" *)

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

"um gráfico tridimensional que consiste em esferas unitárias centradas em 0, 0, 0 e 1, 1, 1"


Agora, para o exemplo em questão,

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

"o 31º elemento de p"

Vamos representar a string acima como uma lista de palavras:

StringSplit[%]

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

e pegue o segundo elemento ...

%[[2]]

31


Estou confuso; onde é pdefinido? EDIT: não importa, eu vejo como você está usando isso; infelizmente não funciona no meu sistema. : - /
Mr.Wizard

Funciona na v.9.0.1. (Lembro-me de que você está usando 7.0.) Sim, p não precisa ser definido.
DavidC

Eu entendo isso agora. No entanto, na v7 eu recebo SpokenString @ p[[117]]a saída " part 117 of p".
precisa saber é o seguinte

Então, SpokenStringé revisado de tempos em tempos. Não me surpreenderia se este código ( codegolf.stackexchange.com/questions/8859/… ) também não funcionasse na versão 7. BTW, não era para ser uma solução duradoura.
DavidC

Hah, eu não tinha visto essa resposta antes.
precisa saber é o seguinte

7

Ruby, 60

Não é tão bom quanto a entrada Perl, mas achei que iria trabalhar nas minhas habilidades em Ruby.

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

A função pega um argumento inteiro ne retorna uma string como a forma ordinal.

Funciona de acordo com a seguinte lógica:
Se o dígito das dezenas for 1 ou o dígito das unidades for maior que 3, use o sufixo 'th'; caso contrário, encontre o sufixo da matriz ['th', 'st', 'nd', 'rd'] usando o dígito final como índice.


o(113)é "113rd", deveria ser "113th". A verificação de dezenas e dígitos não leva em conta números com mais de dois dígitos.
Hammar

Ok, lançou outro %10para compensar. Adicionado 3 caracteres. (Eu sinto que %10aparece suficientes onde ele deve ser encurtadas de alguma forma, mas eu não consigo pensar em uma solução)
Mr. Llama

Você nunca pode bater Perl em escrever código incompreensível horrível que é o mais curto possível :)
jamylak

Defina uma variável para 10?
Wizzwizz4

Eu acho que definir uma variável para n%10é melhor.
CalculadoraFeline

6

Javascript (ES6) 50 44 bytes (não concorrente)

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

Notas

  • leva imput como uma string
  • Removidos 6 bytes, obrigado @ user81655

1
a+-> a+=, remova parênteses, \d-> ., remova [0]e se você pegar o número como uma string: em a.match`1?.$`vez de /1?.$/.exec(a).
user81655

Você provavelmente deve adicionar um aviso de que esta resposta não é concorrente, pois o ES6 não existia quando o desafio foi lançado.
user2428118

5

Javascript, 68 71

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

Esforço conjunto com o ItsCosmo.

EDIT: não estava funcionando corretamente com números> 100


Você poderia trazê-lo para baixo para 62 com: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')e você pode trazê-lo ainda mais para baixo a 54, se você está feliz em usar a notação de seta gordura:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
Wally West

@WallyWest Por alguma razão, eu realmente gosto que minha solução funcione em navegadores modernos. Sinta-se livre para postar sua própria resposta; Eu acho que é suficientemente diferente.
aebabis

Não está bem! Apenas fornecendo algumas alternativas!
Wally West

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

Testando:

*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"]

Deve ser carregado com -XNoMonomorphismRestriction.


3

JavaScript, 64 caracteres (ES3) ou 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'

Explicação

A expressão é n % 100 >> 3 ^ 1avaliada como 0 para qualquer nfinal positivo com dígitos 08- 15. Assim, para qualquer n mod 100que termina no 11, 12ou 13, retorno a matriz de pesquisa undefined, que conduz a um sufixo th.

Para qualquer positivo nfinal em outros dígitos que 08- 15, a expressão n % 100 >> 3 ^ 1é avaliada como um número inteiro positivo, invocando a expressão n % 10para pesquisa de matriz, retornando st, ndou rdpara nque as extremidades com 1, 2ou 3. Caso contrário th,.


Salve um bytes com n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Shaggy

@ Shaggy, obrigado, atualizado conforme sugerido.
Tomas Langkaas


@ guest271314, divertido ver esse código sendo usado. Observe que ele funciona apenas para números positivos, outra alternativa é n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th"adaptada deste post .
Tomas Langkaas

3

APL (Dyalog Unicode) , 38 36 bytes

Obrigado ao ngn por corrigir um erro enquanto mantém a contagem de bytes.

Função de prefixo tácito anônimo. Requer ⎕IO( I ndex O rigin) definido como 0, o que é padrão em muitos sistemas. Até funciona para 0!

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

Experimente online!

{... } lambda anônima; é argumento:

⍳4 primeiros quatro Ɩ ndices;[0,1,2,3]

10↑ pegue os dez primeiros elementos, preenchendo com zeros: [0,1,2,3,0,0,0,0,0,0]

 coloque para tratar como elemento único; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ expandir para uma cópia, uma cópia prototípica (zero), oito cópias;
  [[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],
   ⋮ (mais 5)
   [0,1,2,3,0,0,0,0,0,0]]

ε nlist (achatar);
  [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,
   ⋮ (mais 50)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ gire ciclicamente para a esquerda quantas etapas forem indicadas pelo argumento

 escolha o primeiro número (isto é, o argumento-mod-100º número)

 multiplicam duas por que (dá 0, 2, 4, ou 6)

'thstndrd'↓⍨solte quantos caracteres dessa sequência

2↑ pegue os dois primeiros dos personagens restantes

⍕, concatenar o argumento estrito a esse


"31"?
NGN

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

desculpe, esqueci de mencionar ⎕io←0. Posso ver que você adivinhou isso, mas existem alguns 1,2,3,4,0,0 ... que devem ser 0,1,2,3,0,0 ...
ngn

@ngn Fixed. E passa a trabalhar para 0 também!
Adám

2

PowerShell, 92

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

Funciona com um número por linha de entrada. A entrada é fornecida através do pipeline. Fazer funcionar apenas para um único número não reduz o tamanho.


2

J - 44 char

Nada em J? Isto é um ultraje!

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

Explicado (observe que 1é booleano verdadeiro em J e 0falso):

  • 10 10(...)/@#:]- Primeiro pegamos o argumento ( ]) e encontramos o dígito das dezenas e uns ( 10 10 #:). Em seguida, inseriremos (...)entre os dois.
  • (]*[(~:*])4>])- Nesta subexpressão, mas não a mais interna, ]apontará para o dígito [das unidades e o dígito das dezenas.
  • [(~:*])4>]- ~:é J para "não-iguais", então isso pega o resultado de 4>](ou seja, se um dígito é menor que 4) e o multiplica pelo resultado de tens ~: (4>]). Por que alguém faria isso? Considere o seguinte:
    • Se estamos verificando 10, 11, 12, 13, então tensé 1(estamos na adolescência) e onesé menor que 4, então tens ~: (4>])é falso e o resultado é 0*1= 0.
    • Se formos qualquer outro de {X0, X1, X2, X3}, então claramente tens ~: (4>])é verdade e saímos 1*1= 1.
    • Se onesfor maior que quatro, então 4>]era 0e não importa mais o que acontece com o teste, sairemos 0independentemente.
    • Então, para resumir, [(~:*])4>]é 1se estamos em {X0, X1, X2, X3}, mas não na adolescência e de 0outra forma.
  • ]*- Finalmente multiplicamos esse resultado pelo dígito das unidades. Portanto, este produto será 0se o número merece um 'th'sufixo, senão seu valor.
  • th`st`nd`rd{::~- Utilizamos o dígito de um modificado acima para indexar a lista de sufixos. 0recebe 'th', 1recebe 'st'e assim por diante.
  • ":,- Finalmente, pegue o número original, converta-o em uma string ( ":) e, em seguida, acrescente-o ao sufixo.

O uso é óbvio, embora o verbo como está seja apenas um ordinal, não uma 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 e verificação:

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));
        }
    }
}

Você pode jogar golfe por dois bytes, alterando ||para |.
Kevin Cruijssen

2

Mathematica 29 + 5 = 34 bytes

SpokenStringDump`SpeakOrdinal

+5 bytes porque a Speakfunção deve ser chamada antes de usar este built-in.

Uso

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

Eu sei que este programa não é comparável aos outros. Apenas senti vontade de dar uma solução.

<?$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";}

você pode economizar alguns personagens 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 também:

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"

ungolfed:

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

1

OCaml

Sou bastante novo no OCaml, mas este é o mais curto que pude obter.

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

Eu criei uma função n que usa um número como parâmetro e faz o trabalho. É longo, mas achei que seria ótimo ter um exemplo funcional.


input: 11 produziria saída: 11º

sim, você está certo .. eu fiz a correção. Obrigado
Joseph Elcid

Acabei de arrumar a formatação do seu código. Cada linha precisa ser precedida por quatro espaços para ser reconhecida como um bloco de código.
Gareth

O seu primeiro não seria mais curto se o cheque if v>10 && v<14? Não estou familiarizado com o ocaml, mas é necessário que a string_vvariável seja tão longa?
Gaffi

Não, não é necessário, eu poderia ter escolhido w ou x. Só queria algo significativo. Mas você está certo, isso tornaria o código um pouco mais curto.
Joseph Elcid

1

K - 44 char

Acontece que esse é exatamente o tempo que o J e funciona quase da mesma maneira.

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

Explicado:

  • x$:- Primeiro, convertemos o operando xem uma string e depois atribuímos de volta a x. Nós precisaremos da sua string rep novamente mais tarde, e agora isso salva os caracteres.
  • .:'- Converta ( .:) cada ( ') dígito novamente em um número.
  • -2#0, - Anexe um 0 à frente da lista de dígitos (no caso de números de um dígito) e, em seguida, pegue os dois últimos.
  • {y*(y<4)*~1=x}.- Use os dois dígitos como argumentos xe ypara esta função interna, que retorna yse yfor menor que 4 e xnão é igual a 1, caso contrário, 0.
  • `th`st`nd`rd@ - Indexe a lista de sufixos por este resultado.
  • x,$ - Converta o sufixo do símbolo em sequência e adicione-o ao 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");}

Degolfado:

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");
}

Poderíamos fazer em k=(n-1)%10vez de adicionar 9, mas para n = 0 obteríamos um comportamento incorreto, porque em C é (-1)%10avaliado como -1, e não 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];}

O 11-13 bit está me matando aqui. Funciona para qualquer número inteiro $n >= 0.

Para qualquer número inteiro $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')

Ungolfed:

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

lambda xdefine uma função anônima com o parâmetro x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]define uma tupla das terminações para números menores que 10, o 0-thelemento é para 0e assim por diante. as if ('0'+x)[-2] != '1'verifica se existe 11, 12ou uma 13a correção, e acrescenta, em seguida, else 'th'acrescenta th, em vez de st, rdou nd.


Essa é uma ótima resposta, mas demorei um pouco para entender e entender. Se você pudesse adicionar uma explicação e detalhamento do código abaixo da versão em golf do seu código, isso ajudaria as pessoas a aprender com o seu código e melhorar a qualidade da sua resposta.
Wizzwizz4

Sim eu vou. Devo também adicionar uma resposta não golfe?
NoOneIsHere 25/02

Não deve ser uma resposta diferente ... O que você fez está bem, bem feito. Se você quiser mais desafios, eu poderia dar algumas recomendações.
Wizzwizz4

Está bem. Você pode tentar ... Ajuste sua cadeira ou Onde seus amigos se sentarão . Ou você pode tentar alguns dos meus desafios , como a turnê The Knight's Next . Se esse não é o tipo de desafio que você gosta, basta dizer.
Wizzwizz4

1

JavaScript (Node.js) , 51 bytes

Agradecemos a @KevinCruijssen por melhorar a resposta

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

Experimente online!


Explicação:

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 ainda não há solução R ... não há truques aqui, indexação básica de vetores, que reduziu em três caracteres, graças a Giuseppe. Índice tentado anteriormente: [1+(x%%10)-(x%%100==11)]e [1+(x%%10)*(x%%100!=11)].

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

Experimente online!

Com substr, 79 bytes:

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

Experimente online!


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

@ Giuseppe eu preciso me acalmar entre parênteses :). Uso inteligente de !na frente da expressão em vez de !=.
JayCe

1
Sim, os operadores têm precedência estranha; ^é muito alto, então %%operadores -tipo, em seguida, */e +-e eu acho ==e &|vem a seguir. !tem precedência bastante baixa para que você possa usá-lo como um separador entre operações.
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 deve ser uma string

Eu sei que já sou derrotado pela competição aqui, mas pensei em fornecer minha ideia de qualquer maneira

isso basicamente gera uma lista de pares de chaves e valores com o número (como uma string) final ee o ordinal o. Ele tenta corresponder 'th' primeiro (por isso não usei um dicionário), para que ele não retorne acidentalmente 'st', por exemplo, quando deveria ser 'th'. Isso funcionará para qualquer número inteiro positivo


n[-1]==eé 5 caracteres menor quen.endswith(e)
hlt 14/02

0

C: 95 caracteres

Uma solução ridiculamente longa:

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");}

Precisa ser mutilado mais.


Um usuário sinalizou este ditado "está incorreto: não faz um loop, ou seja, funciona apenas para um determinado número, e não para todos os números abaixo dele. Consulte ideone.com/pO6UwV". Essa não é uma razão para sinalizar, pois os moderadores não julgam a correção, mas pode ser um problema.
dmckee

Com base neste comentário do criador da pergunta: "@Ilmari, estou procurando 11 como entrada e 11 como saída. Não me importo se ele processa várias linhas, mas o que eu tinha em mente era processar apenas um número. - NickC Jan 20 '12 às 21:00 "está fazendo o que deveria. Ou seja, apenas deve processar um único número.
quer

desculpe pela bandeira; Eu interpretei mal o requisito e, na época, não tinha representante suficiente para comentar diretamente. Desculpe de novo. :)
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')
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.