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?
11
entrada e saída, por exemplo11th
? 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?11
como entrada e11th
saí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.Respostas:
Perl, 37 + 1 caracteres
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 ap
opção de linha de comando, assim: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
p
switch conta como um caractere extra .Entrada de amostra:
Resultado:
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.14159
torna-se3rd.14159th
.Como funciona?
Primeiro, essa é uma substituição global do regexp (
s///g
). O regexp sendo correspondido é1?\d\b
, onde\d
corresponde 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\b
corresponde ao último dígito de qualquer número, mais o dígito anterior, se for o caso1
.Na substituição, que é avaliada como código Perl devido à
/e
opçã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:
fonte
g
cancelar 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.Python 2, 49 bytes
Uma função anônima. Um programa completo seria contado em 55 bytes.
'tsnrhtdd'[i::4]
codifica os sufixosth st nd rd
para valores dei
0 a 3. Dado isso, tudo o que precisamos é uma maneira de mapear os valoresn
para o índice do sufixo correspondentei
,. 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 quen%5
dá os mesmos resultados quen%10
para os valores den
com os sufixos especiais. Com um pouco de tentativa e erro, um também pode ser reduzido10<n%100<14
paran%100^15>4
, que pode ser encadeado com o outro condicional para economizar ainda mais bytes.fonte
Python, 68 caracteres
fonte
`i`+"tsnrhtdd"
. Caso contrário, esta é a solução exata que acabei de obter.Mathematica
3945 bytesNota: Nas versões recentes do Mathematica, solicitar a
nth
parte dep
, ondep
é indefinida, gera uma mensagem de erro, mas retorna a resposta correta de qualquer maneira. AdicioneiQuiet
para impedir que a mensagem de erro seja impressa.Uso
Como funciona
SpokenString
grava uma expressão válida do Mathematica conforme possa ser falada. Abaixo estão dois exemplos da documentação para SpokenString ,Agora, para o exemplo em questão,
Vamos representar a string acima como uma lista de palavras:
e pegue o segundo elemento ...
fonte
p
definido? EDIT: não importa, eu vejo como você está usando isso; infelizmente não funciona no meu sistema. : - /SpokenString @ p[[117]]
a saída" part 117 of p"
.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.Ruby, 60
Não é tão bom quanto a entrada Perl, mas achei que iria trabalhar nas minhas habilidades em Ruby.
A função pega um argumento inteiro
n
e 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.
fonte
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.%10
para compensar. Adicionado 3 caracteres. (Eu sinto que%10
aparece suficientes onde ele deve ser encurtadas de alguma forma, mas eu não consigo pensar em uma solução)10
?n%10
é melhor.Javascript (ES6)
5044 bytes (não concorrente)Notas
fonte
a+
->a+=
, remova parênteses,\d
->.
, remova[0]
e se você pegar o número como uma string: ema.match`1?.$`
vez de/1?.$/.exec(a)
.Javascript,
6871Esforço conjunto com o ItsCosmo.
EDIT: não estava funcionando corretamente com números> 100
fonte
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')
Golfscript, 34 caracteres
fonte
Haskell, 95 caracteres
Testando:
Deve ser carregado com -XNoMonomorphismRestriction.
fonte
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 ^ 1
avaliada como 0 para qualquern
final positivo com dígitos08
-15
. Assim, para qualquern mod 100
que termina no11
,12
ou13
, retorno a matriz de pesquisaundefined
, que conduz a um sufixoth
.Para qualquer positivo
n
final em outros dígitos que08
-15
, a expressãon % 100 >> 3 ^ 1
é avaliada como um número inteiro positivo, invocando a expressãon % 10
para pesquisa de matriz, retornandost
,nd
ourd
paran
que as extremidades com1
,2
ou3
. Caso contrárioth
,.fonte
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 deste post .APL (Dyalog Unicode) ,
3836 bytesObrigado 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 como0
, o que é padrão em muitos sistemas. Até funciona para 0!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)2×
multiplicam duas por que (dá0
,2
,4
, ou6
)'thstndrd'↓⍨
solte quantos caracteres dessa sequência2↑
pegue os dois primeiros dos personagens restantes⍕,
concatenar o argumento estrito a essefonte
⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
⎕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 ...PowerShell, 92
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.
fonte
J - 44 char
Nada em J? Isto é um ultraje!
Explicado (observe que
1
é booleano verdadeiro em J e0
falso):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 de4>]
(ou seja, se um dígito é menor que 4) e o multiplica pelo resultado detens ~: (4>])
. Por que alguém faria isso? Considere o seguinte:tens
é1
(estamos na adolescência) eones
é menor que 4, entãotens ~: (4>])
é falso e o resultado é0*1
=0
.tens ~: (4>])
é verdade e saímos1*1
=1
.ones
for maior que quatro, então4>]
era0
e não importa mais o que acontece com o teste, sairemos0
independentemente.[(~:*])4>]
é1
se estamos em {X0, X1, X2, X3}, mas não na adolescência e de0
outra forma.]*
- Finalmente multiplicamos esse resultado pelo dígito das unidades. Portanto, este produto será0
se 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.0
recebe'th'
,1
recebe'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.
fonte
C #, 62 bytes
Programa completo e verificação:
fonte
||
para|
.Mathematica 29 + 5 = 34 bytes
+5 bytes porque a
Speak
função deve ser chamada antes de usar este built-in.Uso
fonte
PHP, 151
Eu sei que este programa não é comparável aos outros. Apenas senti vontade de dar uma solução.
fonte
foreach($s as $n){echo$n;
Scala 86
Scala 102:
102 também:
ungolfed:
fonte
OCaml
Sou bastante novo no OCaml, mas este é o mais curto que pude obter.
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.
fonte
if v>10 && v<14
? Não estou familiarizado com o ocaml, mas é necessário que astring_v
variável seja tão longa?K - 44 char
Acontece que esse é exatamente o tempo que o J e funciona quase da mesma maneira.
Explicado:
x$:
- Primeiro, convertemos o operandox
em uma string e depois atribuímos de volta ax
. 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 argumentosx
ey
para esta função interna, que retornay
sey
for menor que 4 ex
nã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:
fonte
C -
9583 caracteresDegolfado:
Poderíamos fazer em
k=(n-1)%10
vez de adicionar 9, mas para n = 0 obteríamos um comportamento incorreto, porque em C é(-1)%10
avaliado como -1, e não 9.fonte
Javascript, 75
fonte
PHP, 98 bytes
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
fonte
Python,
8884 bytesUngolfed:
lambda x
define uma função anônima com o parâmetrox
.((('th','st','nd','rd')+('th',)*6)[int(x[-1])]
define uma tupla das terminações para números menores que 10, o0-th
elemento é para0
e assim por diante. asif ('0'+x)[-2] != '1'
verifica se existe11
,12
ou uma13
a correção, e acrescenta, em seguida,else 'th'
acrescentath
, em vez dest
,rd
ound
.fonte
JavaScript (Node.js) , 51 bytes
Agradecemos a @KevinCruijssen por melhorar a resposta
Experimente online!
Explicação:
fonte
R ,
7976 bytesComo 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)]
.Experimente online!
Com
substr
, 79 bytes:Experimente online!
fonte
1+x%%10*!x%%100==11
para o índice?!
na frente da expressão em vez de!=
.^
é 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.Python 2.7, 137 caracteres
n
deve ser uma stringEu 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
e
e o ordinalo
. 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 positivofonte
n[-1]==e
é 5 caracteres menor quen.endswith(e)
C: 95 caracteres
Uma solução ridiculamente longa:
Precisa ser mutilado mais.
fonte
Javascript, 75
fonte
Oracle SQL 11.2, 101 bytes
fonte
Javascript ES6, 52 caracteres
fonte