Sortie des nombres ordinaux (1er, 2e, 3e)

43

Je voudrais générer (en tant que résultat d'une fonction ou simplement en tant que sortie d'un programme) le suffixe ordinal d'un entier positif concaténé au nombre.

Échantillons:

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

Et ainsi de suite, avec le suffixe répétant le sous-motif initial 1-10 tous les 10 jusqu'à 100, où le motif recommence à la fin.

L'entrée serait le nombre et la sortie la chaîne ordinale, comme indiqué ci-dessus.

Quel est le plus petit algorithme pour cela?

Nicole
la source
Bonjour, NickC, et bienvenue sur codegolf.SE! Juste pour clarifier, voulez-vous dire que nous devrions lire un nombre comme 11entrée et une sortie par exemple 11th? Chaque numéro de l'entrée est-il sur une ligne distincte, et les numéros de sortie doivent-ils également figurer sur des lignes séparées? Et devons-nous gérer plus d’une ligne d’entrée?
Ilmari Karonen
1
Cherchez-vous le plus petit algorithme ou le plus petit code?
Toto
@Ilmari je cherche 11en entrée et 11then sortie. Cela ne me dérange pas si elle traite plusieurs lignes, mais ce que je pensais, c’était traiter un seul numéro.
Nicole
@ M42 Vous savez, je ne suis pas vraiment sûr. Je n'ai pas d'exigence stricte - mais je pensais probablement au plus petit algorithme.
Nicole

Réponses:

30

Perl, 37 + 1 caractères

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

Il s'agit d'une substitution d'expressions rationnelles qui ajoute le suffixe ordinal approprié à tous les nombres $_non suivis d'une lettre. Pour l'appliquer à l'entrée de fichier, utilisez le pcommutateur de ligne de commande, comme suit:

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

Il s'agit d'un programme Perl complet qui lit les entrées de stdin et écrit les sorties traitées dans stdout. Le code actuel est long de 37 caractères, mais le pcommutateur compte pour un caractère supplémentaire .

Exemple de saisie:

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

Sortie:

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

Les nombres déjà suivis de lettres seront ignorés, ainsi, alimenter à nouveau la sortie à travers le filtre ne la changera pas. Les espaces, les virgules et les points entre les nombres ne sont pas traités spécialement. Ils sont donc supposés séparer les chiffres comme toute autre ponctuation. Ainsi, par exemple 3.14159devient 3rd.14159th.

Comment ça marche?

  • Tout d’abord, il s’agit d’un regexp global ( s///g). L'expression rationnelle étant adapté est 1?\d\b, le cas \dcorrespond à un chiffre et \bune assertion de longueur nulle correspondant à la limite entre un alphanumérique et un caractère non alphanumérique. Ainsi, 1?\d\bcorrespond au dernier chiffre d’un nombre, plus le chiffre précédent s’il se trouve 1.

  • Dans la substitution, qui est évaluée en tant que code Perl en raison du /ecommutateur, nous prenons la chaîne correspondante segment ( $&) et lui ajoutons .le suffixe obtenu en s’utilisant $&lui-même en tant qu’indice entier de la liste (0,st,nd,rd); si ce suffixe est zéro ou non défini (c’est-à-dire quand $&zéro ou plus grand que trois), l’ ||opérateur le remplace th.


Edit: Si la saisie est limitée à un seul entier, cette solution à 35 caractères suffira:

s/1?\d$/$&.((0,st,nd,rd)[$&]||th)/e
Ilmari Karonen
la source
1
Doit pouvoir supprimer la gsubstitution si vous spécifiez que chaque numéro doit figurer sur sa propre ligne. En outre, cela vous permettrait de changer la limite de mots pour être $. Mais dans l’ensemble, +1, solution sacrément astucieuse.
M. Lama
@ GigaWatt: En effet, j'avais écrit le code avant que NickC ne réponde à ma question sur le format d'entrée, donc je l'ai rendu aussi générique que possible.
Ilmari Karonen
38

Python 2, 49 octets

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

Une fonction anonyme. Un programme complet serait compté à 55 octets.

'tsnrhtdd'[i::4]encode les suffixes th st nd rdpour les valeurs de i0 à 3. Compte tenu de cela, tous nous avons besoin est un moyen de cartographier les valeurs de nl'indice du suffixe correspondant i. Une expression simple qui fonctionne est (n%10)*(n%10<4 and 10<n%100<14). Nous pouvons facilement abréger ce problème en supprimant le premier ensemble de parenthèses et en observant n%5les résultats obtenus avec les mêmes n%10valeurs que pour les nsuffixes spéciaux. Avec un peu d'essais et d'erreurs, on peut aussi raccourcir 10<n%100<14le n%100^15>4, ce qui peut être enchaîné avec l'autre conditionnel pour économiser encore plus d'octets.

Xsot
la source
3
c'est un peu de magie noire ici c:
chat
Je ne comprends pas. Quelqu'un peut-il expliquer ce qui se passe ici?
Pavel
@Pavel J'ai mis à jour ma réponse avec une explication.
xsot
Impressionnant! Excellente façon de penser ...
Benison Sam
10

Python, 68 caractères

i=input()
k=i%10
print"%d%s"%(i,"tsnrhtdd"[(i/10%10!=1)*(k<4)*k::4])
Gareth
la source
4
C'est vraiment tard, mais vous pouvez enlever 7 octets en faisant `i`+"tsnrhtdd". Sinon, c'est la solution exacte que je viens de recevoir.
DLosc
10

Mathematica 39 45 octets

Remarque: Dans les versions récentes de Mathematica, demander la nthpartie de p, où pest indéfinie, génère un message d'erreur, mais renvoie néanmoins la réponse correcte. J'ai ajouté Quietpour empêcher le message d'erreur de l'impression.

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

Usage

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

31ème

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

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


Comment ça marche

SpokenStringécrit une expression Mathematica valide telle qu’elle pourrait être parlée. Vous trouverez ci-dessous deux exemples tirés de la documentation de SpokenString .

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

"racine carrée de la quantité x sur la quantité y plus z" *)

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

"un graphique tridimensionnel constitué de sphères unitaires centrées à 0, 0, 0 et 1, 1, 1"


Maintenant, pour l'exemple en main,

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

"le 31ème élément de p"

Représentons la chaîne ci-dessus sous forme de liste de mots:

StringSplit[%]

{"le", "31ème", "élément", "de", "p"}

et prenez le deuxième élément ...

%[[2]]

31ème

DavidC
la source
Je suis confus; où est pdéfini? EDIT: ça ne fait rien, je vois comment vous utilisez ceci; Malheureusement, cela ne fonctionne pas sur mon système. : - /
Mr.Wizard
Cela fonctionne sur v.9.0.1. (Je crois me souvenir que vous utilisez 7.0.) Oui, p n'a pas besoin d'être défini.
DavidC
Je comprends cela maintenant. Cependant, en v7, je reçois de SpokenString @ p[[117]]la sortie " part 117 of p".
Mr.Wizard
Ainsi SpokenStringest révisé de temps en temps. Je ne serais pas surpris si ce code ( codegolf.stackexchange.com/questions/8859/… ) ne fonctionne pas non plus sur le v. 7. Au fait, il ne s'agissait pas d'une solution durable.
DavidC
Hah, je n'avais pas vu cette réponse avant.
Mr.Wizard
7

Ruby, 60 ans

Ce n'est pas aussi bon que l'entrée Perl, mais je me suis dit que je travaillerais sur mes compétences en Ruby.

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

Fonction prend un argument entier n, et renvoie une chaîne sous la forme ordinale.

Fonctionne selon la logique suivante:
Si le chiffre des dizaines est un 1 ou que le chiffre des unités est supérieur à 3, utilisez le suffixe 'th'; sinon, trouvez le suffixe dans le tableau ['th', 'st', 'nd', 'rd'] en utilisant le dernier chiffre comme index.

M. Lama
la source
o(113)est "113rd", devrait être "113th". La vérification des dizaines ne prend pas en compte les nombres de plus de deux chiffres.
Hammar
Ok, jeté dans un autre %10pour compenser. Ajout de 3 caractères. (Je me sens comme %10semble assez où il devrait être raccourcies en quelque sorte, mais je ne peux pas penser à une solution)
M. Llama
Vous ne pouvez jamais battre Perl dans l' écriture de code incompréhensible horrible de ce aussi court que possible :)
jamylak
Définir une variable sur 10?
wizzwizz4
Je pense que définir une variable à n%10est mieux.
CalculatriceFeline
6

Javascript (ES6) 50 44 octets (non concurrents)

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

Remarques

  • prend comme une ficelle
  • Suppression de 6 octets, merci @ utilisateur81655
Shaun H
la source
1
a+-> a+=, supprime les parenthèses, \d-> ., supprime [0]et si vous prenez le nombre sous forme de chaîne: a.match`1?.$`au lieu de /1?.$/.exec(a).
user81655
Vous devriez probablement ajouter une notification indiquant que cette réponse est non concurrente, car ES6 n'existait pas au moment de la publication du défi.
user2428118
5

Javascript, 68 71

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

Effort conjoint avec ItsCosmo.

EDIT: ne fonctionnait pas correctement avec des nombres> 100

Aebabis
la source
Vous pouvez le réduire à 62 avec: function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')et vous pouvez le réduire davantage à 54 si vous préférez utiliser la notation des grosses flèches:o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
WallyWest
@WallyWest Pour une raison quelconque, j'aime beaucoup le fait que ma solution fonctionne dans les navigateurs modernes. N'hésitez pas à poster votre propre réponse; Je pense que c'est suffisamment différent.
aebabis
Non, c'est bon! Juste fournir quelques alternatives!
WallyWest
3

Golfscript, 34 caractères

~.10/10%1=!1$10%*.4<*'thstndrd'2/=
hammar
la source
3

Haskell, 95 caractères

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

Essai:

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

Doit être chargé avec -XNoMonomorphismRestriction.

Will Ness
la source
3

JavaScript, 64 caractères (ES3) ou 47 caractères (ES6)

ES3 (64 caractères):

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

ES6 (47 caractères):

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

Explication

L'expression est n % 100 >> 3 ^ 1évaluée à 0 pour toute nfin positive avec chiffres 08- 15. Ainsi, pour toute n mod 100fin dans 11, 12ou 13, la recherche de tableau retourne undefined, conduisant à un suffixe de th.

Pour tout positif nse terminant dans d' autres chiffres que 08- 15, l'expression est n % 100 >> 3 ^ 1évaluée à un nombre entier positif, en invoquant l'expression n % 10pour la recherche de réseau, le retour st, ndou rdpour nqui se termine avec 1, 2, ou 3. Dans le cas contraire, th.

Tomas Langkaas
la source
Enregistrer un octet avec n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Shaggy
@Shaggy, merci, mis à jour comme suggéré.
Tomas Langkaas
@ guest271314, amusant de voir ce code utilisé. Notez que cela ne fonctionne que pour les nombres positifs, une autre alternative est n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", adaptée de ce post .
Tomas Langkaas
3

APL (Dyalog Unicode) , 38 à 36 octets

Merci à ngn pour avoir corrigé un bogue tout en maintenant le nombre d'octets.

Fonction de préfixe tacite anonyme. Nécessite ⎕IO( I ndex O ensemble à RIGINE) 0, qui est par défaut sur de nombreux systèmes. Même travaille pour 0!

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

Essayez-le en ligne!

{} Lambda anonyme; est l'argument:

⍳4 quatre premières ɩ ndices;[0,1,2,3]

10↑ prenez les dix premiers éléments de cela, en ajoutant des zéros: [0,1,2,3,0,0,0,0,0,0]

 joindre à traiter comme un seul élément; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ développer à une copie, une copie prototype (tout à zéro), huit copies;
  [[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 autres)
   [0,1,2,3,0,0,0,0,0,0]]

ε nlist (aplatir);
  [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 de plus)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ faire une rotation cyclique à gauche autant de pas que l'indique l'argument

 choisir le premier nombre (c'est-à-dire le nombre argument-mod-100)

 multiplier par deux que (donne 0, 2, 4, ou 6)

'thstndrd'↓⍨déposer autant de caractères de cette chaîne

2↑ prendre les deux premiers des personnages restants

⍕, concaténer l'argument stringifié à celui

Adam
la source
"31"?
ngn
⍕,{2↑'thstndrd'↓⍨2×⊃⍵⌽∊1 0 8\⊂10↑⍳4}
IGN
désolé, j'ai oublié de mentionner ⎕io←0. Je vois que vous avez deviné, mais il y en a quelques 1,2,3,4,0,0 ... qui devraient être 0,1,2,3,0,0 ...
dès
@ ngn fixe. Et arrive à travailler pour 0 aussi!
Adám
2

PowerShell, 92

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

Fonctionne avec un numéro par ligne d'entrée. L'entrée est donnée par le pipeline. Le faire fonctionner pour un seul nombre ne réduit pas la taille.

Joey
la source
2

J - 44 caractères

Rien dans J? C'est un outrage!

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

Expliqué (notez que le 1booléen est vrai en J et qu'il 0est faux):

  • 10 10(...)/@#:]- Prenons d'abord l'argument ( ]) et trouvons le chiffre des dizaines et des un ( 10 10 #:). Ensuite, nous allons insérer (...)entre les deux.
  • (]*[(~:*])4>])- Dans cette sous-expression, mais pas la plus profonde, ]indiquera le chiffre des unités et [le chiffre des dizaines.
  • [(~:*])4>]- ~:est J pour "non-égal", donc cela prend le résultat de 4>](c'est-à-dire si le chiffre est inférieur ou égal à 4) et le multiplie par le résultat de tens ~: (4>]). Pourquoi quelqu'un ferait-il cela? Considérer ce qui suit:
    • Si nous vérifions 10, 11, 12, 13, alors tensest 1(nous sommes dans l'adolescence) et onesest inférieur à 4, donc tens ~: (4>])est faux et le résultat est 0*1= 0.
    • Si nous sommes un autre de {X0, X1, X2, X3}, alors clairement tens ~: (4>])est vrai et nous sortons 1*1= 1.
    • Si onesest supérieur à quatre, alors 4>]c'était 0et peu importe ce qu'il advient du test, nous sortirons quand 0même.
    • Donc, pour résumer, [(~:*])4>]est 1si nous sommes dans {X0, X1, X2, X3} mais pas dans les adolescents, et 0autrement.
  • ]*- Enfin, nous multiplions ce résultat par le chiffre des unités. Donc, ce produit sera 0si le nombre mérite un 'th'suffixe, sinon sa valeur.
  • th`st`nd`rd{::~- Nous utilisons les chiffres modifiés en haut pour indexer la liste des suffixes. 0obtient 'th', 1obtient 'st', et ainsi de suite.
  • ":,- Enfin, prenez le numéro d'origine, convertissez-le en chaîne ( ":), puis ajoutez-le au suffixe.

L'utilisation est évidente, même si le verbe en l'état ne peut prendre qu'un ordinal, pas une liste.

   (":,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|
+----+----+----+----+----+----+----+----+----+----+
algorithmeshark
la source
2

C #, 62 octets

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

Programme complet et vérification:

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));
        }
    }
}
adrianmp
la source
Vous pouvez jouer au golf par deux octets en changeant la ||pour |.
Kevin Cruijssen
2

Mathematica 29 + 5 = 34 octets

SpokenStringDump`SpeakOrdinal

+5 octets car la Speakfonction doit être appelée avant d'utiliser cette fonction intégrée.

Usage

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "

JungHwan Min
la source
1

PHP, 151

Je sais que ce programme n'est pas comparable aux autres. Juste envie de donner une solution.

<?$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";}
l0n3sh4rk
la source
vous pouvez enregistrer quelques caractères en utilisantforeach($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 également:

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))
      }
Utilisateur inconnu
la source
1

OCaml

Je suis assez nouveau sur OCaml, mais c’est le plus court que je puisse obtenir.

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

J'ai créé une fonction n qui prend un nombre en paramètre et fait le travail. C'est long mais j'ai pensé que ce serait génial d'avoir un exemple fonctionnel.

Joseph Elcid
la source
entrée: 11 donnerait une sortie: 11e
oui, tu as raison .. J'ai corrigé. Merci
Joseph Elcid
Je viens de ranger le formatage de votre code. Chaque ligne doit être précédée de quatre espaces pour être reconnue en tant que bloc de code.
Gareth
Votre première si la vérification est-elle plus courte if v>10 && v<14? Je ne connais pas bien ocaml, mais est-il nécessaire que la string_vvariable soit aussi longue?
Gaffi
Non ce n'est pas nécessaire, j'aurais pu choisir w ou x. Je voulais juste quelque chose de significatif. Mais vous avez raison, le code aurait été un peu plus court.
Joseph Elcid
1

K - 44 caractères

Il se trouve que cela est exactement aussi long que le J et fonctionne presque de la même manière.

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

A expliqué:

  • x$:- Nous convertissons d'abord l'opérande xen chaîne, puis nous lui attribuons de nouveau x. Nous aurons besoin de son représentant de chaîne ultérieurement, afin de le sauvegarder maintenant.
  • .:'- Reconvertir ( .:) chaque 'chiffre ( ) en un nombre.
  • -2#0, - Ajoutez un 0 au début de la liste des chiffres (dans le cas de nombres à un chiffre), puis prenez les deux derniers.
  • {y*(y<4)*~1=x}.- Utilisez les deux chiffres comme arguments xet yà cette fonction interne, qui renvoie ysi yest inférieur à 4 et xn’est pas égal à 1, sinon 0.
  • `th`st`nd`rd@ - Indexez la liste des suffixes par ce résultat.
  • x,$ - Convertissez le suffixe de symbole en chaîne et ajoutez-le au numéro d'origine.

Usage:

  {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")
algorithmeshark
la source
1

C - 95 83 caractères

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

Nous pourrions faire k=(n-1)%10au lieu d’ajouter 9, mais pour n = 0, nous aurions un comportement incorrect, car C (-1)%10évalue à -1, pas à 9.

pawel.boczarski
la source
1

Javascript, 75

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

PHP, 98 octets

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

Le bit 11-13 me tue ici. Fonctionne pour tout entier $n >= 0.

Pour tout entier $n:

PHP, 103 octets

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];}
ricdesi
la source
1

Python, 88 84 octets

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 xdéfinit une fonction anonyme avec paramètre x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]définit un tuple des fins pour les nombres inférieurs à 10, l' 0-thélément est pour 0, et ainsi de suite. les if ('0'+x)[-2] != '1'contrôles s'il y a 11, 12ou un 13à fixer, et ajoute else 'th'ajoute au thlieu de st, rdou nd.

Il n'y a personne
la source
C'est une excellente réponse, mais il m'a fallu un certain temps pour le comprendre et le comprendre. Si vous pouviez ajouter une explication de code et une ventilation sous la version jouée de votre code, cela aiderait les gens à tirer les leçons de votre code et à améliorer la qualité de votre réponse.
wizzwizz4
Ok je le ferai Devrais-je également ajouter une réponse sans jeu?
NoOneIsHere
La réponse ne devrait pas être différente ... Ce que vous avez fait est bien, bien fait. Si vous voulez plus de défis à faire, je pourrais faire quelques recommandations.
wizzwizz4
D'accord. Vous pouvez essayer ... Ajustez votre chaise ou vos copains . Ou vous pourriez essayer certains de mes défis , tels que The Knight's Next Tour . Si ce n’est pas le genre de défis que vous aimez, dites simplement.
wizzwizz4
1

JavaScript (Node.js) , 51 octets

crédit à @KevinCruijssen pour l'amélioration de la réponse

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

Essayez-le en ligne!


Explication:

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


la source
1

R , 79 76 octets

Puisqu'il n'y a pas encore de solution R ... pas d'astuce ici, index de base de vecteur, golfé jusqu'à 3 caractères grâce à Giuseppe. Index précédemment essayé: [1+(x%%10)-(x%%100==11)]et [1+(x%%10)*(x%%100!=11)].

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

Essayez-le en ligne!

Avec substr79 octets:

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

Essayez-le en ligne!

JayCe
la source
1
1+x%%10*!x%%100==11pour l'index?
Giuseppe
@ Giuseppe, j'ai besoin de me calmer sur la parenthèse :). Utilisation intelligente de !devant l'expression au lieu de !=.
JayCe
1
Oui, les opérateurs ont une priorité étrange; ^est vraiment élevé, puis les %%opérateurs de type, puis */et +-et je pense ==et &|vient ensuite. !La priorité est assez faible, vous pouvez donc l'utiliser comme séparateur entre les opérations.
Giuseppe
0

Python 2.7, 137 caractères

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 devrait être une chaîne

Je sais que je suis déjà battu par la concurrence ici, mais je pensais donner mon idée quand même.

ceci génère simplement une liste de paires clé / valeur avec un nombre (sous forme de chaîne) se terminant eet l'ordinal o. Il essaie de faire correspondre "th" en premier (d'où la raison pour laquelle je n'ai pas utilisé de dictionnaire), afin qu'il ne retourne pas accidentellement "st", par exemple, alors qu'il doit être "th". Cela fonctionnera pour tout entier positif

veste
la source
n[-1]==eest de 5 caractères plus court quen.endswith(e)
hlt
0

C: 95 caractères

Une solution ridiculement longue:

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

Il doit être mutilé davantage.

Fors
la source
Un utilisateur a signalé que "est incorrect: ne fait pas de boucle du tout, c’est-à-dire que cela fonctionne uniquement pour un nombre donné, et non pas pour tous les nombres inférieurs. Voir ideone.com/pO6UwV." Ce n'est pas une raison pour signaler que les modérateurs ne jugent pas l'exactitude, mais cela peut être un problème.
dmckee
Sur la base de ce commentaire du créateur de la question: "@Ilmari, je cherche 11 en entrée et 11 en sortie. Cela ne me dérange pas de traiter plusieurs lignes, mais ce que j'avais en tête, c'était de traiter un seul nombre. - NickC Jan 20 '12 à 21:00 "il fait ce qu'il devrait. C'est-à-dire qu'il ne devrait traiter qu'un seul numéro.
Fors
désolé pour ce drapeau; J'ai mal interprété l'exigence et je n'avais pas assez de représentants à l'époque pour commenter directement. Encore pardon. :)
Will Ness
0

Javascript, 75

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

Oracle SQL 11.2, 101 octets

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

Javascript ES6, 52 caractères

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Qwertiy
la source