Emissione di numeri ordinali (1 °, 2 °, 3 °)


43

Vorrei generare (come risultato di ritorno di una funzione, o semplicemente come output di un programma) il suffisso ordinale di un intero positivo concatenato al numero.

Campioni:

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

E così via, con il suffisso che ripete il sottopattern 1-10 iniziale ogni 10 fino a 100, dove il modello alla fine ricomincia.

L'input sarebbe il numero e l'output della stringa ordinale come mostrato sopra.

Qual è l'algoritmo più piccolo per questo?


Ciao, NickC, e benvenuto su codegolf.SE! Giusto per chiarire, vuoi dire che dovremmo leggere un numero come 11input e output, ad esempio 11th? Ogni numero nell'input è su una riga separata e anche i numeri dell'output devono essere su righe separate? E dobbiamo gestire più di una riga di input?
Ilmari Karonen,

1
Stai cercando l'algoritmo più piccolo o il codice più piccolo?
Tot

@Ilmari Sto cercando 11come input e 11thcome output. Non mi importa se elabora più righe ma quello che avevo in mente era l'elaborazione di un solo numero.
Nicole,

@ M42 Sai, non ne sono davvero sicuro. Non ho un requisito rigoroso, ma probabilmente stavo pensando all'algoritmo più piccolo.
Nicole,

Risposte:


30

Perl, 37 + 1 caratteri

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

Questa è una sostituzione regexp che aggiunge il suffisso ordinale appropriato a tutti i numeri $_che non sono già seguiti da una lettera. Per applicarlo all'input del file, utilizzare l' popzione della riga di comando, in questo modo:

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

Questo è un programma Perl completo che legge l'input da stdin e scrive l'output elaborato su stdout. Il codice effettivo è lungo 37 caratteri, ma l' pinterruttore conta come un carattere in più .

Input di esempio:

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

Produzione:

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

I numeri già seguiti dalle lettere verranno ignorati, quindi alimentare di nuovo l'output attraverso il filtro non lo cambierà. Spazi, virgole e punti tra i numeri non vengono trattati in modo speciale, quindi si presume che separino i numeri come qualsiasi altra punteggiatura. Così, ad esempio, 3.14159diventa 3rd.14159th.

Come funziona?

  • Innanzitutto, si tratta di una sostituzione regexp globale ( s///g). La regexp da abbinare è 1?\d\b, dove \dcorrisponde a qualsiasi cifra ed \bè un'asserzione di larghezza zero che corrisponde al confine tra un carattere alfanumerico e un carattere non alfanumerico. Pertanto, 1?\d\bcorrisponde all'ultima cifra di qualsiasi numero, più la cifra precedente se risulta essere 1.

  • Nella sostituzione, che viene valutata come codice Perl a causa dello /eswitch, prendiamo il segmento stringa corrispondente ( $&) e aggiungiamo ( .) ad esso il suffisso ottenuto usando $&se stesso come indice intero nell'elenco (0,st,nd,rd); se questo suffisso è zero o indefinito (ovvero quando $&è zero o maggiore di tre), l' ||operatore lo sostituisce con th.


Modifica: se l'input è limitato a un singolo numero intero, sarà sufficiente questa soluzione di 35 caratteri:

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

1
Dovrebbe essere in grado di eliminare la gsostituzione se si specifica che ogni numero deve essere sulla propria riga. Inoltre, ciò ti permetterebbe di cambiare la parola limite in modo che sia $. Ma nel complesso, +1, soluzione dannatamente intelligente.
Mr. Llama,

@GigaWatt: In effetti, ho scritto il codice prima che NickC rispondesse alla mia domanda sul formato di input, quindi l'ho reso il più generico possibile.
Ilmari Karonen,

38

Python 2, 49 byte

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

Una funzione anonima. Un programma completo verrebbe conteggiato a 55 byte.

'tsnrhtdd'[i::4]codifica i suffissi th st nd rdper valori ida 0 a 3. Detto questo, tutti abbiamo bisogno è un modo per mappare i valori nper l'indice del suffisso corrispondente i. Un'espressione semplice che funziona è (n%10)*(n%10<4 and 10<n%100<14). Possiamo accorciarlo facilmente facendo cadere la prima serie di parentesi e osservando che n%5fornisce gli stessi risultati n%10dei valori ncon i suffissi speciali. Con un po 'di tentativi ed errori, si può anche ridurre 10<n%100<14a n%100^15>4, che può essere concatenato con l'altra condizionale per risparmiare ancora di più byte.


3
questa è una magia nera proprio qui c:
gatto


Non capisco Qualcuno può spiegare cosa sta succedendo qui?
Pavel,

@Pavel Ho aggiornato la mia risposta con una spiegazione.
xsot,

Eccezionale! Modo brillante di pensare ...
Benison Sam,

10

Python, 68 caratteri

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

4
Questo è davvero tardi, ma puoi toglierlo 7 byte facendo `i`+"tsnrhtdd". Altrimenti, questa è la soluzione esatta che ho appena ricevuto.
DLosc,

10

Mathematica 39 45 byte

Nota: nelle versioni recenti di Mathematica, la richiesta della nthparte di p, dove pnon è definita, genera un messaggio di errore, ma restituisce comunque la risposta corretta. Ho aggiunto Quietper impedire la stampa del messaggio di errore.

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

uso

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

31

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

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


Come funziona

SpokenStringscrive un'espressione Mathematica valida come potrebbe essere detta. Di seguito sono riportati due esempi dalla documentazione per SpokenString ,

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

"radice quadrata della quantità x sulla quantità y più z" *)

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

"un grafico tridimensionale costituito da sfere unitarie centrate su 0, 0, 0 e 1, 1, 1"


Ora, per l'esempio a portata di mano,

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

"il 31 ° elemento di p"

Rappresentiamo la stringa sopra come un elenco di parole:

StringSplit[%]

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

e prendi il secondo elemento ...

%[[2]]

31


Non ho capito bene; dove è pdefinito? EDIT: non importa, vedo come lo stai usando; purtroppo non funziona sul mio sistema. : - /
Mr.Wizard,

Funziona su v.9.0.1. (Mi sembra di ricordare che stai usando 7.0.) Sì, non è necessario definire p.
DavidC,

Lo capisco adesso. Tuttavia, nella v7 ottengo SpokenString @ p[[117]]dall'output " part 117 of p".
Mr.Wizard,

Quindi SpokenStringviene rivisto di volta in volta. Non sarei sorpreso che questo codice ( codegolf.stackexchange.com/questions/8859/… ) non funzioni anche su v. 7. A proposito, non doveva essere una soluzione duratura.
DavidC,

Ah, non avevo mai visto quella risposta prima.
Mr.Wizard,

7

Ruby, 60 anni

Non è buono come la voce Perl, ma ho pensato che avrei lavorato sulle mie abilità di Ruby.

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

La funzione accetta un argomento intero ne restituisce una stringa come forma ordinale.

Funziona secondo la seguente logica:
Se la cifra delle decine è 1 o quella più grande di 3 usa il suffisso 'th'; altrimenti trova il suffisso dall'array ['th', 'st', 'nd', 'rd'] usando la cifra finale come indice.


o(113)è "113rd", dovrebbe essere "113th". Il controllo delle decine non tiene conto dei numeri con più di due cifre.
Hammar,

Ok, ne ho lanciato un altro %10per compensare. Aggiunti 3 caratteri. (Mi sembra che %10appaia abbastanza dove dovrebbe essere abbreviato in qualche modo, ma non riesco a pensare a una soluzione)
Mr. Llama

Non puoi mai battere Perl scrivendo un codice orribile e incomprensibile il più breve possibile :)
jamylak,

Impostare una variabile su 10?
wizzwizz4,

Penso che impostare una variabile su n%10sia meglio.
CalculatorFeline

6

Javascript (ES6) 50 44 byte (non concorrenti)

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

Gli appunti

  • prende imput come una stringa
  • Rimossi 6 byte, grazie @ user81655

1
a+-> a+=, rimuovi le parentesi, \d-> ., rimuovi [0]e se prendi il numero come stringa: a.match`1?.$`anziché /1?.$/.exec(a).
user81655,

Probabilmente dovresti aggiungere un avviso che questa risposta non è competitiva, poiché ES6 non esisteva quando la sfida è stata pubblicata.
user2428118,

5

Javascript, 68 71

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

Sforzo congiunto con ItsCosmo.

EDIT: non funzionava correttamente con numeri> 100


Puoi portarlo a 62 con: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')e puoi portarlo ulteriormente a 54 se sei felice di usare la notazione con la freccia grassa:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
WallyWest

@WallyWest Per qualche ragione, mi piace molto che la mia soluzione funzioni nei browser moderni. Sentiti libero di pubblicare la tua risposta; Penso che sia sufficientemente diverso.
aebabis

No, va bene! Basta fornire alcune alternative!
WallyWest

3

Golfscript, 34 caratteri

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

3

Haskell, 95 caratteri

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

test:

*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 essere caricato con -XNoMonomorphismRestriction.


3

JavaScript, 64 caratteri (ES3) o 47 caratteri (ES6)

ES3 (64 caratteri):

function(n){return n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'}

ES6 (47 caratteri):

n=>n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'

Spiegazione

L'espressione n % 100 >> 3 ^ 1restituisce 0 per qualsiasi nfinale positivo con cifre 08- 15. Pertanto, per qualsiasi n mod 100desinenza in 11, 12o 13, la ricerca di array ritorna undefined, portando a un suffisso di th.

Per qualsiasi positivo ndesinenza in altre cifre rispetto 08- 15, l'espressione n % 100 >> 3 ^ 1restituisce un intero positivo, invocando l'espressione n % 10per la ricerca di matrice, di ritorno st, ndo rdper nla quale termina con 1, 2o 3. In caso contrario, th.


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

@Shaggy, grazie, aggiornato come suggerito.
Tomas Langkaas,


@ guest271314, divertente vedere questo codice in uso. Nota che funziona solo con numeri positivi, un'altra alternativa è n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", adattata da questo post .
Tomas Langkaas,

3

APL (Dyalog Unicode) , 38 36 byte

Grazie a ngn per aver corretto un bug mantenendo il conteggio dei byte.

Funzione prefisso tacito anonimo. Richiede ⎕IO( I ndex O rigin ) impostato su 0, che è predefinito su molti sistemi. Funziona anche per 0!

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

Provalo online!

{... } lambda anonimo; è argomento:

⍳4 primi quattro d ndices;[0,1,2,3]

10↑ prendi i primi dieci elementi da quello, riempiendo di zeri: [0,1,2,3,0,0,0,0,0,0]

 allegare per trattare come singolo elemento; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ espandersi in una copia, una copia prototipica (tutto zero), otto copie;
  [[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 in più)
   [0,1,2,3,0,0,0,0,0,0]]

ϵ nlist (appiattisci);
  [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,
   ⋮ (altri 50)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ ruota ciclicamente a sinistra tutti i passaggi indicati dall'argomento

 scegli il primo numero (ovvero l'argomento-mod-100'th number)

 moltiplicare due da quella (dà 0, 2, 4, o 6)

'thstndrd'↓⍨rilasciare tanti caratteri da questa stringa

2↑ prendi i primi due dei personaggi rimanenti

⍕, concatenare l'argomento stretto a quello


"31"?
ngn,

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

scusa, ho dimenticato di menzionare ⎕io←0. Vedo che hai indovinato, ma ci sono alcuni 1,2,3,4,0,0 ... che dovrebbero essere 0,1,2,3,0,0 ...
ngn

@ngn fisso. E sembra funzionare anche per 0!
Adám,

2

PowerShell, 92

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

Funziona con un numero per riga di input. L'input viene fornito attraverso la pipeline. Farlo funzionare per un solo numero non riduce le dimensioni.


2

J - 44 caratteri

Niente in J? Questo è un oltraggio!

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

Spiegato (nota che 1è booleano vero in J ed 0è falso):

  • 10 10(...)/@#:]- Per prima cosa prendiamo l'argomento ( ]) e troviamo le decine e quelle digit ( 10 10 #:). Quindi, inseriremo (...)tra i due.
  • (]*[(~:*])4>])- In questa sottoespressione, ma non quella più interna, ]punterà alla cifra di una e [alla cifra delle decine.
  • [(~:*])4>]- ~:è J per "non-uguale", quindi questo prende il risultato di 4>](cioè se una cifra è inferiore a 4) e la moltiplica per il risultato di tens ~: (4>]). Perché qualcuno dovrebbe farlo? Considera quanto segue:
    • Se stiamo controllando 10, 11, 12, 13, allora tensè 1(siamo adolescenti) ed onesè inferiore a 4, quindi tens ~: (4>])è falso e il risultato è 0*1= 0.
    • Se siamo qualcun altro di {X0, X1, X2, X3}, allora chiaramente tens ~: (4>])è vero e usciamo 1*1= 1.
    • Se onesè maggiore di quattro, allora 4>]era 0e non importa più cosa succede al test, 0usciremo comunque.
    • Quindi, per riassumere, [(~:*])4>]è 1se siamo in {X0, X1, X2, X3} ma non negli adolescenti, e 0altrimenti.
  • ]*- Alla fine moltiplichiamo quel risultato per le singole cifre. Quindi questo prodotto lo sarà 0se il numero merita un 'th'suffisso, altrimenti il ​​suo valore.
  • th`st`nd`rd{::~- Usiamo la cifra di una cifra modificata dall'alto per indicizzare l'elenco dei suffissi. 0ottiene 'th', 1ottiene 'st'e così via.
  • ":,- Infine, prendi il numero originale, convertilo in una stringa ( ":), quindi anteponilo al suffisso.

L'uso è ovvio, sebbene così com'è il verbo può prendere solo un ordinale, non un elenco.

   (":,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 byte

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

Programma completo e verifica:

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

Puoi giocare a golf di due byte cambiando ||in |.
Kevin Cruijssen

2

Mathematica 29 + 5 = 34 byte

SpokenStringDump`SpeakOrdinal

+5 byte perché la Speakfunzione deve essere chiamata prima di utilizzare questo built-in.

uso

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

So che questo programma non è paragonabile agli altri. Volevo solo dare una soluzione.

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

puoi salvare alcuni personaggi usandoforeach($s as $n){echo$n;
karthik il

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 pure:

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

Sono abbastanza nuovo per OCaml, ma questo è il più breve che potessi ottenere.

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

Ho creato una funzione n che accetta un numero come parametro e fa il lavoro. È lungo ma ho pensato che sarebbe stato bello avere un esempio funzionale.


input: 11 produrrebbe output:

si, hai ragione .. ho fatto la correzione. Grazie
Joseph Elcid,

Ho appena riordinato la formattazione del tuo codice. Ogni riga deve essere preceduta da quattro spazi per essere riconosciuta come un blocco di codice.
Gareth,

Non sarebbe il tuo primo se il controllo fosse più corto come if v>10 && v<14? Non ho familiarità con ocaml, ma è necessario che la string_vvariabile sia così lunga?
Gaffi,

No non è necessario, avrei potuto scegliere w o x. Volevo solo qualcosa di significativo. Ma hai ragione, avrebbe reso il codice un po 'più breve.
Joseph Elcid,

1

K - 44 caratteri

Succede che questo è esattamente lungo quanto la J e funziona quasi allo stesso modo.

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

Ha spiegato:

  • x$:- Innanzitutto, convertiamo l'operando xin una stringa, quindi lo riassegniamo a x. Avremo bisogno di nuovo il suo rep string in seguito, quindi farlo ora salva i caratteri.
  • .:'- Converti ( .:) ciascuna ( ') cifra in un numero.
  • -2#0, - Aggiungi uno 0 all'inizio dell'elenco di cifre (nel caso di numeri a una cifra), quindi prendi le ultime due.
  • {y*(y<4)*~1=x}.- Utilizzare le due cifre come argomenti xe yper questa funzione interna, che restituisce yse yè inferiore a 4 e xnon è uguale a 1, altrimenti 0.
  • `th`st`nd`rd@ - Indicizza l'elenco dei suffissi per questo risultato.
  • x,$ - Converti il ​​suffisso dal simbolo alla stringa e aggiungilo al numero originale.

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 caratteri

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

Potremmo fare k=(n-1)%10invece di aggiungere 9, ma per n = 0 otterremmo un comportamento errato, perché in C viene (-1)%10valutato -1, non 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 byte

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

L'11-13 bit mi sta uccidendo qui. Funziona per qualsiasi numero intero $n >= 0.

Per qualsiasi numero intero $n:

PHP, 103 byte

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 byte

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 xdefinisce una funzione anonima con parametro x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]definisce una tupla delle terminazioni per numeri inferiori a 10, l' 0-thelemento è per 0e così via. i if ('0'+x)[-2] != '1'controlli se c'è 11, 12o una 13di correzione, e aggiunge poi else 'th'aggiunge th, invece di st, rdo nd.


Questa è un'ottima risposta, ma mi ci è voluto un po 'per capire e capirla. Se potessi aggiungere una spiegazione del codice e un'analisi sotto la versione golf del tuo codice, ciò aiuterebbe le persone a imparare dal tuo codice e migliorare la qualità della tua risposta.
wizzwizz4,

Ok, lo farò. Devo anche aggiungere una risposta senza golf?
NoOneIsHere il

Non dovrebbe essere una risposta diversa ... Quello che hai fatto va bene, ben fatto. Se volete ulteriori sfide da fare, potrei dare alcuni consigli.
wizzwizz4,

Ok. Potresti provare ... Regola la sedia o Dove siederanno i tuoi amici . Oppure potresti provare alcune delle mie sfide , come The Knight's Next Tour . Se questi non sono il tipo di sfide che ti piacciono, basta dire.
wizzwizz4,

1

JavaScript (Node.js) , 51 byte

merito a @KevinCruijssen per migliorare la risposta

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

Provalo online!


Spiegazione :

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 byte

Dal momento che non esiste ancora una soluzione R ... nessun trucco, indicizzazione vettoriale di base, ridotto a 3 caratteri grazie a Giuseppe. Indice precedentemente provato: [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])

Provalo online!

Con substr, 79 byte:

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

Provalo online!


1
1+x%%10*!x%%100==11per l'indice?
Giuseppe,

@Giuseppe ho bisogno di calmarmi sulla parentesi :). Uso intelligente di !fronte a espressione anziché !=.
JayCe,

1
Sì, gli operatori hanno una strana precedenza; ^è davvero alto, quindi %%operatori di tipo, quindi */ed +-e penso ==e &|viene dopo. !ha una precedenza piuttosto bassa, quindi puoi usarlo come separatore tra le operazioni.
Giuseppe,

0

Python 2.7, 137 caratteri

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 dovrebbe essere una stringa

So di essere già battuto dalla competizione qui, ma ho pensato di fornire comunque la mia idea

questo in pratica genera un elenco di chiavi, coppie di valori con il numero (come stringa) ee l'ordinale o. Tenta di abbinare prima "th" (quindi perché non ho usato un dizionario), in modo che non restituisca accidentalmente "st", ad esempio, quando dovrebbe essere "th". Questo funzionerà per qualsiasi numero intero positivo


n[-1]==eè di 5 caratteri più breve din.endswith(e)
hlt

0

C: 95 caratteri

Una soluzione ridicolmente lunga:

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

Deve essere più distrutto.


Un utente ha segnalato questo messaggio "non è corretto: non esegue alcun ciclo, vale a dire funziona solo per un determinato numero, non per tutti i numeri sottostanti. Vedi ideone.com/pO6UwV." Non è un motivo per segnalare che i moderatori non giudicano la correttezza, ma potrebbe essere un problema.
dmckee,

Sulla base di questo commento del creatore della domanda: "@Ilmari Sto cercando 11 come input e 11 come output. Non mi dispiace se elabora più righe ma quello che avevo in mente era l'elaborazione di un solo numero. - NickC Jan 20 'alle 21:00 "sta facendo quello che dovrebbe. Cioè dovrebbe solo elaborare un singolo numero.
Fors l'

scusa per quella bandiera; Ho letto male il requisito, e non avevo abbastanza rappresentante al momento, per commentare direttamente. Ancora una volta mi dispiace. :)
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 byte

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 caratteri

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.