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?


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

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.


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

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


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.


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

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


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/=

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.


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.


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


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


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|
+----+----+----+----+----+----+----+----+----+----+

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

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 "


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

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

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.


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

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.


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

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.


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


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!


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


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.


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

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

0

Javascript ES6, 52 caractères

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.