Ordnungszahlen ausgeben (1., 2., 3.)


43

Ich möchte (als Ergebnis einer Funktion oder einfach als Ausgabe eines Programms) das Ordnungssuffix einer positiven Ganzzahl erzeugen, die mit der Zahl verkettet ist.

Proben:

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

Und so weiter, mit dem Suffix, das alle 10 bis 100 das erste Untermuster von 1 bis 10 wiederholt, wo das Muster schließlich von vorne beginnt.

Die Eingabe wäre die Zahl und die Ausgabe die Ordnungszahl wie oben gezeigt.

Was ist der kleinste Algorithmus dafür?


Hallo NickC, und willkommen bei codegolf.SE! Meinen Sie zur Verdeutlichung, dass wir eine Zahl wie 11zB als Eingabe und Ausgabe lesen sollten 11th? Befindet sich jede Zahl in der Eingabe in einer separaten Zeile und sollten sich die Ausgabenummern auch in separaten Zeilen befinden? Und müssen wir mehr als eine Eingabezeile verarbeiten?
Ilmari Karonen

1
Suchen Sie den kleinsten Algorithmus oder den kleinsten Code?
Toto

@Ilmari Ich suche 11als Input und 11thals Output. Es macht mir nichts aus, wenn es mehrere Zeilen verarbeitet, aber ich hatte vor, nur eine einzige Zahl zu verarbeiten.
Nicole

@ M42 Weißt du, ich bin mir nicht sicher. Ich habe keine strengen Anforderungen - aber ich habe wahrscheinlich an den kleinsten Algorithmus gedacht.
Nicole

Antworten:


30

Perl, 37 + 1 Zeichen

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

Hierbei handelt es sich um eine reguläre Ausdrücke-Ersetzung, bei der den Zahlen, auf $_die noch kein Buchstabe folgt, das entsprechende Ordnungssuffix angehängt wird . Verwenden Sie die pBefehlszeilenoption wie folgt, um sie auf die Dateieingabe anzuwenden :

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

Dies ist ein vollständiges Perl-Programm, das Eingaben aus stdin liest und die verarbeitete Ausgabe in stdout schreibt. Der tatsächliche Code ist 37 Zeichen lang, aber der pSchalter zählt als ein zusätzliches Zeichen .

Beispieleingabe:

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

Ausgabe:

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

Zahlen, auf die bereits Buchstaben folgen, werden ignoriert. Wenn Sie also die Ausgabe erneut durch den Filter führen, wird dies nicht geändert. Leerzeichen, Kommas und Punkte zwischen Zahlen werden nicht speziell behandelt, daher wird davon ausgegangen, dass sie Zahlen wie jede andere Interpunktion trennen. So zB 3.14159wird 3rd.14159th.

Wie funktioniert es?

  • Erstens ist dies ein globaler regulärer Ausdruck ( s///g). Die regexp wird abgestimmt ist 1?\d\b, in dem \dübereinstimmt jede Ziffer und \beine Null-Breite Assertion die Grenze zwischen einem alphanumerischen passenden und einem nicht-alphanumerischen Zeichen. Somit 1?\d\bentspricht die letzte Ziffer einer beliebigen Zahl, plus die vorherige Stelle , wenn es passiert zu sein 1.

  • In der Ersetzung, die aufgrund des /eSwitches als Perl-Code ausgewertet wird , nehmen wir das übereinstimmende Zeichenfolgensegment ( $&) und hängen ( .) das Suffix an, das sich $&selbst als ganzzahliger Index für die Liste ergibt (0,st,nd,rd). Wenn dieses Suffix Null oder undefiniert ist (dh wenn $&Null oder größer als Drei ist), ersetzt der ||Operator es durch th.


Bearbeiten: Wenn die Eingabe auf eine einzelne Ganzzahl beschränkt ist, reicht diese 35-stellige Lösung aus:

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

1
Sollte in der Lage sein, gdie Substitution abzubrechen, wenn Sie angeben, dass sich jede Nummer in einer eigenen Zeile befinden muss. Außerdem könnten Sie dadurch die Wortgrenze ändern $. Aber insgesamt +1, verdammt clevere Lösung.
Mr. Llama

@GigaWatt: In der Tat habe ich den Code geschrieben, bevor NickC meine Frage zum Eingabeformat beantwortete, also habe ich ihn so allgemein wie möglich gestaltet.
Ilmari Karonen

38

Python 2, 49 Bytes

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

Eine anonyme Funktion. Ein volles Programm würde mit 55 Bytes gezählt.

'tsnrhtdd'[i::4]codiert die Suffixe th st nd rdfür Werte ivon 0 bis 3. Vor diesem Hintergrund ist es nur erforderlich, die Werte von nauf den Index des entsprechenden Suffixes abzubilden i. Ein klarer Ausdruck, der funktioniert, ist (n%10)*(n%10<4 and 10<n%100<14). Wir können dies leicht verkürzen, indem wir den ersten Satz von Klammern fallen lassen und beobachten, dass sich n%5dieselben Ergebnisse ergeben wie n%10für die Werte nmit den speziellen Suffixen. Mit einem bisschen von Versuch und Irrtum kann man verkürzen auch 10<n%100<14zu n%100^15>4, die mit den anderen bedingten verkettet werden können , um noch mehr zu sparen Bytes.


3
das ist etwas schwarze Magie hier c:
Katze


Ich verstehe es nicht. Kann mir jemand erklären, was hier passiert?
Pavel

@Pavel Ich habe meine Antwort mit einer Erklärung aktualisiert.
Xsot

Genial! Geniale
Denkweise

10

Python, 68 Zeichen

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

4
Das ist wirklich spät, aber Sie können 7 Bytes abheben, indem Sie tun `i`+"tsnrhtdd". Ansonsten ist dies die genaue Lösung, die ich gerade erhalten habe.
DLosc,

10

Mathematica 39 45 Bytes

Hinweis: In neueren Versionen von Mathematica wird bei der Abfrage des nthTeils von p, wo nicht pdefiniert, eine Fehlermeldung generiert, die richtige Antwort wird jedoch trotzdem zurückgegeben. Ich habe hinzugefügt Quiet, um zu verhindern, dass die Fehlermeldung gedruckt wird.

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

Verwendungszweck

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

31st

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


Wie es funktioniert

SpokenStringSchreibt einen gültigen Mathematica-Ausdruck aus, wie er gesprochen werden könnte. Nachfolgend finden Sie zwei Beispiele aus der Dokumentation für SpokenString :

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

"Quadratwurzel der Menge x über der Menge y plus z" *)

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

eine dreidimensionale Grafik, die aus Einheitskugeln besteht, die bei 0, 0, 0 und 1, 1, 1 zentriert sind


Nun zum vorliegenden Beispiel:

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

"das 31. Element von p"

Lassen Sie uns die obige Zeichenfolge als eine Liste von Wörtern darstellen:

StringSplit[%]

{"das", "31.", "Element", "von", "p"}

und nimm das zweite Element ...

%[[2]]

31st


Ich bin verwirrt; wo ist pdefiniert EDIT: egal, ich sehe, wie du das verwendest; Leider funktioniert es nicht auf meinem System. : - /
Mr.Wizard

Es funktioniert auf v.9.0.1. (Ich erinnere mich anscheinend, dass Sie 7.0 verwenden.) Ja, p muss nicht definiert werden.
DavidC

Das verstehe ich jetzt. In v7 bekomme ich jedoch von SpokenString @ p[[117]]der Ausgabe " part 117 of p".
Mr.Wizard

Also SpokenStringwird von Zeit zu Zeit überarbeitet. Es würde mich nicht wundern, wenn dieser Code ( codegolf.stackexchange.com/questions/8859/… ) auch auf Version 7 nicht funktioniert. Übrigens war er keine dauerhafte Lösung.
DavidC

Hah, ich hatte diese Antwort noch nie gesehen.
Mr.Wizard

7

Rubin, 60

Es ist nicht so gut wie der Perl-Eintrag, aber ich dachte, ich würde an meinen Ruby-Fähigkeiten arbeiten.

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

Function akzeptiert ein ganzzahliges Argument nund gibt eine Zeichenfolge als Ordnungszahl zurück.

Funktioniert nach der folgenden Logik:
Wenn die Zehnerstelle eine 1 ist oder die Einerstelle größer als 3 ist, verwenden Sie das Suffix 'th'; Andernfalls suchen Sie das Suffix aus dem Array ['th', 'st', 'nd', 'rd'] mit der letzten Ziffer als Index.


o(113)ist "113rd", sollte sein "113th". Die Zehnerstellenprüfung berücksichtigt keine Zahlen mit mehr als zwei Stellen.
Hammar

Ok, wirf einen anderen ein %10, um das zu kompensieren. 3 Zeichen hinzugefügt. (Ich glaube, es %10scheint genug, wo es irgendwie verkürzt werden sollte, aber ich kann mir keine Lösung
vorstellen

Sie können Perl niemals schlagen, indem Sie einen schrecklich unverständlichen Code schreiben, der so kurz wie möglich ist :)
jamylak

Variable setzen auf 10?
wizzwizz4

Ich finde n%10es besser , eine Variable auf zu setzen .
CalculatorFeline

6

Javascript (ES6) 50 44 Bytes (nicht konkurrierend)

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

Anmerkungen

  • Nimmt den Input als String
  • 6 Bytes entfernt, danke @ user81655

1
a+-> a+=, entferne Klammern, \d-> ., entferne [0]und wenn du die Zahl als Zeichenkette nimmst: a.match`1?.$`statt /1?.$/.exec(a).
User81655

Sie sollten wahrscheinlich einen Hinweis hinzufügen, dass diese Antwort nicht konkurrierend ist, da ES6 zum Zeitpunkt der Veröffentlichung der Herausforderung nicht vorhanden war.
user2428118

5

Javascript, 68 71

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

Gemeinsame Anstrengung mit ItsCosmo.

BEARBEITEN: Funktionierte nicht richtig mit Zahlen> 100


Sie können es mit: auf 62 function o(n)n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')o=n=>n+([,'st','nd','rd'][~~(n/10%10)-1?n%10:0]||'th')
senken

@WallyWest Aus irgendeinem Grund gefällt mir sehr, dass meine Lösung in modernen Browsern funktioniert. Fühlen Sie sich frei, Ihre eigene Antwort zu posten; Ich denke, es ist ausreichend anders.
Aebabis

Nein. Das ist in Ordnung! Ich biete nur ein paar Alternativen an!
WallyWest

3

Golfscript, 34 Zeichen

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

3

Haskell, 95 Zeichen

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

Testen:

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

Muss mit -XNoMonomorphismRestriction geladen werden.


3

JavaScript, 64 Zeichen (ES3) oder 47 Zeichen (ES6)

ES3 (64 Zeichen):

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

ES6 (47 Zeichen):

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

Erläuterung

Der Ausdruck wird n % 100 >> 3 ^ 1für alle positiven nEndungen mit Ziffern 08- mit 0 bewertet 15. So kann jede n mod 100endet in 11, 12, oder 13, die Rendite Lookup - Array undefined, was zu einem Suffix th.

Für jede positive nEnde in anderen Stellen als 08- 15die Expressions n % 100 >> 3 ^ 1auswertet auf eine positive ganze Zahl ist , die Expression Aufruf n % 10für Array - Lookup, Return st, ndoder rdfür nderen Enden mit 1, 2, oder 3. Ansonsten th.


Speichern Sie ein Byte mit n+=[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'.
Shaggy

@ Shaggy, danke, aktualisiert wie vorgeschlagen.
Tomas Langkaas


@ guest271314, es macht Spaß zu sehen, wie dieser Code verwendet wird. Beachten Sie, dass es nur für positive Zahlen funktioniert, eine andere Alternative ist n+=[,"st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10]||"th", aus diesem Beitrag angepasst .
Tomas Langkaas

3

APL (Dyalog Unicode) , 38 36 Bytes

Vielen Dank an ngn für die Behebung eines Fehlers bei gleichzeitiger Beibehaltung der Byteanzahl.

Anonyme implizite Präfixfunktion. Requires ⎕IO( I ndex O rigin) auf gesetzt 0, was bei vielen Systemen Standard ist. Funktioniert sogar für 0!

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

Probieren Sie es online!

{} Anonymes Lambda; ist Argument:

⍳4 ersten vier ɩ ndices;[0,1,2,3]

10↑ Nimm die ersten zehn Elemente davon und fülle sie mit Nullen auf: [0,1,2,3,0,0,0,0,0,0]

 umschließen, um als einzelnes Element zu behandeln; [[0,1,2,3,0,0,0,0,0,0]]

1 0 8\ Erweitern auf eine Kopie, eine prototypische Kopie (alle null), acht Kopien;
  [[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 weitere)
   [0,1,2,3,0,0,0,0,0,0]]

ϵ nlist (Abflachen);
  [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 weitere)
   0,1,2,3,0,0,0,0,0,0]

⍵⌽ Drehe zyklisch so viele Schritte nach links, wie das Argument angibt

 wähle die erste Zahl (dh die argument-mod-100'te Zahl)

 multiplizieren zwei davon (gibt 0, 2, 4, oder 6)

'thstndrd'↓⍨Löschen Sie so viele Zeichen aus dieser Zeichenfolge

2↑ nimm die ersten zwei der verbleibenden Charaktere

⍕, verketten das stringifizierte Argument dazu


"31."?
3.

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

Entschuldigung, ich habe vergessen zu erwähnen ⎕io←0. Ich kann sehen, dass Sie das erraten haben, aber es gibt ein paar 1,2,3,4,0,0 ..., die 0,1,2,3,0,0 ... sein sollten
ngn

@ngn Behoben. Und funktioniert zufällig auch für 0!
Adám

2

PowerShell, 92

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

Arbeitet mit einer Nummer pro Eingabezeile. Die Eingabe erfolgt über die Pipeline. Wenn es nur für eine einzelne Zahl funktioniert, wird die Größe nicht reduziert.


2

J - 44 Zeichen

Nichts in J? Das ist ein Skandal!

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

Erklärt (beachten Sie, dass 1in J boolescher Wert true und 0false ist):

  • 10 10(...)/@#:]- Zuerst nehmen wir das Argument ( ]) und finden die Zehner- und Einerstelle ( 10 10 #:). Dann werden wir (...)zwischen den beiden einfügen .
  • (]*[(~:*])4>])- In diesem Unterausdruck, aber nicht im innersten, ]wird auf die Einerstelle und [die Zehnerstelle gezeigt.
  • [(~:*])4>]- ~:Ist J für "nicht gleich", so nimmt dies das Ergebnis von 4>](dh ob die eine Ziffer kleiner als 4 ist oder nicht) und multipliziert es mit dem Ergebnis von tens ~: (4>]). Warum sollte jemand das tun? Folgendes berücksichtigen:
    • Wenn wir 10, 11, 12, 13 überprüfen, dann tensist 1(wir sind im Teenageralter) und onesist kleiner als 4, tens ~: (4>])ist also falsch und das Ergebnis ist 0*1= 0.
    • Wenn wir irgendein anderes von {X0, X1, X2, X3} sind, dann tens ~: (4>])ist dies eindeutig wahr und wir steigen aus 1*1= 1.
    • Wenn onesgrößer als vier ist, dann 4>]war 0und es egal ist, was mit dem Test passiert, werden wir trotzdem 0rauskommen.
    • Zusammenfassend lässt [(~:*])4>]sich 1sagen, ob wir uns in {X0, X1, X2, X3} befinden, aber nicht im Teenageralter und 0ansonsten.
  • ]*- Schließlich multiplizieren wir dieses Ergebnis mit der Einerstelle. So wird dieses Produkt sein, 0wenn die Zahl ein 'th'Suffix verdient , sonst seinen Wert.
  • th`st`nd`rd{::~- Wir verwenden die modifizierte Einerstelle von oben, um die Liste der Suffixe zu indizieren. 0bekommt 'th', 1bekommt 'st'und so weiter.
  • ":,- Nehmen Sie zum Schluss die ursprüngliche Nummer, konvertieren Sie sie in eine Zeichenfolge ( ":) und stellen Sie sie vor das Suffix.

Die Verwendung ist offensichtlich, obwohl das Verb wie es ist nur eine Ordnungszahl annehmen kann, keine 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 Bytes

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

Vollständiges Programm und Überprüfung:

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

Sie können Golf spielen es durch zwei Bytes durch die Veränderung ||an |.
Kevin Cruijssen

2

Mathematica 29 + 5 = 34 Bytes

SpokenStringDump`SpeakOrdinal

+5 Byte, da die SpeakFunktion aufgerufen werden muss, bevor diese integrierte Funktion verwendet werden kann.

Verwendungszweck

SpokenStringDump`SpeakOrdinal[1]

"1st "

SpokenStringDump`SpeakOrdinal[4707]

"4,707th "


1

PHP, 151

Ich weiß, dass dieses Programm nicht mit den anderen vergleichbar ist. Ich wollte nur eine Lösung finden.

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

Sie können ein paar Zeichen speichern, indem Sieforeach($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 auch:

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

Ich bin ziemlich neu in OCaml, aber dies ist die kürzeste, die ich bekommen konnte.

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

Ich habe eine Funktion n erstellt, die eine Zahl als Parameter verwendet und die Arbeit erledigt. Es ist lang, aber ich dachte, es wäre großartig, ein funktionales Beispiel zu haben.


Eingabe: 11 würde Ausgabe ergeben: 11st

Ja, du hast recht. Ich habe die Korrektur vorgenommen. Vielen Dank
Joseph Elcid

Ich habe gerade die Formatierung Ihres Codes aufgeräumt. Vor jeder Zeile müssen vier Leerzeichen stehen, um als Codeblock erkannt zu werden.
Gareth

Wäre Ihr erster Check nicht kürzer als if v>10 && v<14? Ocaml ist mir nicht vertraut, aber muss die string_vVariable so lang sein?
Gaffi

Nein, es ist nicht notwendig, ich hätte w oder x wählen können. Ich wollte nur etwas Sinnvolles. Aber Sie haben Recht, es hätte den Code etwas kürzer gemacht.
Joseph Elcid

1

K - 44 Zeichen

Es kommt also vor, dass dies genau so lang ist wie das J und fast genauso funktioniert.

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

Erklärt:

  • x$:- Zuerst konvertieren wir den Operanden xin einen String und weisen diesen dann wieder zu x. Wir werden die Zeichenfolgenwiederholung später noch einmal benötigen. Dadurch werden jetzt Zeichen gespeichert.
  • .:'- Wandle ( .:) jede ( ') Ziffer zurück in eine Zahl.
  • -2#0, - Fügen Sie der Ziffernliste eine 0 voran (bei einstelligen Zahlen) und nehmen Sie dann die letzten beiden.
  • {y*(y<4)*~1=x}.- Verwenden Sie die beiden Ziffern als Argumente xund yfür diese innere Funktion, die zurückgibt, ywenn ykleiner als 4 und xnicht gleich 1 ist, andernfalls 0.
  • `th`st`nd`rd@ - Indizieren Sie die Liste der Suffixe nach diesem Ergebnis.
  • x,$ - Konvertieren Sie das Suffix von symbol in string und hängen Sie es an die ursprüngliche Nummer an.

Verwendungszweck:

  {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 Zeichen

main(n,k){scanf("%d",&n);k=(n+9)%10;printf("%d%s\n",n,k<3?"st\0nd\0rd"+3*k:"th");}

Entgolfet:

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

Wir könnten tun, k=(n-1)%10anstatt 9 zu addieren, aber für n = 0 würden wir ein falsches Verhalten erhalten, weil in C (-1)%10-1 ausgewertet wird, nicht 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];}

Das 11-13 Bit bringt mich hier um. Funktioniert für jede ganze Zahl $n >= 0.

Für eine beliebige ganze Zahl $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 xDefiniert eine anonyme Funktion mit Parameter x. ((('th','st','nd','rd')+('th',)*6)[int(x[-1])]Definiert ein Tupel der Endungen für Zahlen unter 10, das 0-thElement ist für 0und so weiter. die if ('0'+x)[-2] != '1'überprüft , ob es gibt 11, 12oder eine 13zu beheben, und fügt dann else 'th'fügt thstatt st, rdoder nd.


Dies ist eine großartige Antwort, aber es hat eine Weile gedauert, bis ich sie verstanden habe. Wenn Sie eine Code-Erklärung und eine Aufschlüsselung unterhalb der Golf-Version Ihres Codes hinzufügen könnten, könnten die Leute aus Ihrem Code lernen und die Qualität Ihrer Antwort verbessern.
wizzwizz4

Ok, ich werde. Sollte ich auch eine Antwort ohne Golf hinzufügen?
NoOneIsHere

Es sollte keine andere Antwort sein ... Was Sie getan haben, ist in Ordnung, gut gemacht. Wenn Sie weitere Herausforderungen haben möchten, kann ich Ihnen einige Empfehlungen geben.
wizzwizz4

Okay. Sie könnten versuchen, ... Ihren Stuhl anzupassen , oder wo werden Ihre Freunde sitzen . Oder Sie könnten einige meiner Herausforderungen ausprobieren , wie zum Beispiel The Knight's Next Tour . Wenn dies nicht die Art von Herausforderungen sind, die Sie mögen, sagen Sie einfach.
wizzwizz4

1

JavaScript (Node.js) , 51 Byte

Dank an @KevinCruijssen für die Verbesserung der Antwort

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

Probieren Sie es online!


Erklärung:

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

Da es noch keine R-Lösung gibt ... hier keine Tricks, grundlegende Vektorindizierung, dank Giuseppe 3 Zeichen weniger. Bereits ausprobierter Index: [1+(x%%10)-(x%%100==11)]und [1+(x%%10)*(x%%100!=11)].

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

Probieren Sie es online!

Mit substr79 Bytes:

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

Probieren Sie es online!


1
1+x%%10*!x%%100==11für den Index?
Giuseppe

@ Giuseppe Ich muss mich auf der Klammer beruhigen :). Clevere Verwendung !vor dem Ausdruck statt !=.
JayCe

1
Ja, die Operatoren haben einen seltsamen Vorrang. ^ist wirklich hoch, dann %%Typ Operatoren, dann */und +-und ich denke ==und &|kommt als nächstes. !hat eine recht niedrige Priorität, sodass Sie sie als Trennzeichen zwischen Operationen verwenden können.
Giuseppe

0

Python 2.7, 137 Zeichen

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 sollte eine Zeichenfolge sein

Ich weiß, dass mich die Konkurrenz hier bereits geschlagen hat, aber ich dachte, ich würde trotzdem meine Idee einbringen

Dies erzeugt im Grunde genommen eine Liste von Schlüsseln, Wertepaaren mit der Endung number (als Zeichenfolge) eund der Ordnungszahl o. Es wird versucht, zuerst 'th' zu finden (daher habe ich kein Wörterbuch verwendet), damit es nicht versehentlich 'st' zurückgibt, zum Beispiel, wenn es 'th' sein sollte. Dies funktioniert für jede positive ganze Zahl


n[-1]==eist 5 Zeichen kürzer alsn.endswith(e)
hlt

0

C: 95 Zeichen

Eine lächerlich lange Lösung:

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

Es muss mehr verstümmelt werden.


Ein Benutzer meldete diesen Spruch "ist falsch: Schleifen überhaupt nicht, dh es funktioniert nur für eine bestimmte Zahl, nicht für _alle_ Zahlen darunter. Siehe ideone.com/pO6UwV." Das ist kein Grund, als Moderatoren zu markieren, die die Richtigkeit nicht beurteilen, aber es kann ein Problem sein.
dmckee

Gestützt auf diesen Kommentar des Fragestellers: "@Ilmari Ich suche 11 als Eingabe und 11 als Ausgabe. Es macht mir nichts aus, wenn es mehrere Zeilen verarbeitet, aber ich hatte vor, nur eine einzige Zahl zu verarbeiten. - NickC Jan 20 '12 at 21:00 "es tut was es sollte. Dh es sollte nur eine einzelne Nummer verarbeitet werden.
Fors

Entschuldigung für diese Flagge; Ich habe die Anforderung falsch verstanden und hatte zu diesem Zeitpunkt nicht genügend Mitarbeiter, um direkt zu kommentieren. Entschuldigung nochmal. :)
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 Zeichen

n=>n+(!/1.$/.test(--n)&&'snr'[n%=10]+'tdd'[n]||'th')
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.