Ordnungszahlprüfung

17

Beschreibung :

Überprüfen Sie anhand einer Zeichenfolge als Eingabe, ob es sich um eine gültige Ordnungszahl in Englisch handelt. Wenn es gültig ist, geben Sie den Wahrheitswert zurück, andernfalls geben Sie den falschen Wert zurück. (Vorgeschlagen von @Arnauld. Danke. Auch von @JoKing)

Für Benutzer, die über Ordnungszahlen wissen wollen, gehen Sie hier:

https://www.mathsisfun.com/numbers/cardinal-ordinal-chart.html (Vorschlag von: qwr)

Mögliche Eingaben:

21st ---> true
12nd ---> false
1nd ---> false
....

Dies ist eine Code-Golf- Herausforderung, so dass der kürzeste Code in jeder Sprache der Gewinner ist.

Beispiele:

console.log('12th' , true) // This evaluates to true
console.log('1st' , true) // also evaluates to true
console.log('21nd' , false) // returns false
console.log('11st' , false) // returns false
console.log('111199231923819238198231923213123909808th' , true) // true

Da viele Leute die Frage gestellt haben, ob Eingaben nur gültige Zeichenfolgen sind oder nicht:

Alle Eingaben sind immer gültig. Das heißt, sie haben die Form eines Strings und bestehen aus einer Ziffer (oder einer Anzahl von Ziffern) zusammen mit einem der vier Suffixe:

st, nd, rd,th

Muhammad Salman
quelle
Können Sie die Regeln der Ordnungszahlen klären? Oder setzen Sie zumindest einen Link zu den Regeln, denen Sie folgen.
Qwr
Sie sind normale Regeln. Ich habe nichts geändert. Aber danke für die Eingabe, ich habe einen Link hinzugefügt
Muhammad Salman
@ Jonathan Allan Ordnungszahlen beginnen mit 1st, negative Ordnungszahlen existieren nicht - english.stackexchange.com/questions/309713/…
Oliver Ni
@ JonathanAllan OP sagt: "Die Eingabe wird ein gültiges Ordnungsmuster sein." was bedeutet, keine negativen
Oliver Ni
2
Sie sagen, die Eingaben sind immer gültig, aber ich denke, ein besserer Begriff wäre gut formuliert . Sowohl der 12. als auch der 12. sind gut geformt aber nur der erstere ist gültig .
David Conrad

Antworten:

3

Bash + GNU-Dienstprogramme , 54

Regex-Matching scheint ein einfacher Weg zu sein. Ich bin mir ziemlich sicher, dass dieser Ausdruck mehr verkürzt werden könnte:

egrep '((^|[^1])(1st|2nd|3rd)|(1.|(^|[^1])[^1-3])th)$'

Eingabe von STDIN. Ausgabe als Shell-Rückkehrcode - 0 ist wahr und 1 ist falsch.

Probieren Sie es online!

Digitales Trauma
quelle
Was denn Dies gibt nicht die richtige Antwort aus.
Muhammad Salman
@ MuhammadSalman Das liegt daran, dass es sich um eine Testsuite handelt. Schauen Sie sich die Exit-Codes für 1stund an 1th.
Dennis
egrepist in der Lage zu addieren und die Primalität zu testen (in unary), daher denke ich, dass Sie dies zu einer egrep Antwort machen können.
Dennis
Es tut mir leid, aber meine Prügelei ist scheiße. Ich habe mich gelangweilt, also habe ich einen Diff-Checker verwendet, um den Unterschied zwischen Eingabe und Ausgabe zu überprüfen. Ich verstehe dein Argument. Also habe ich jetzt eine Frage @Dennis: Hat Bash Booleaner?
Muhammad Salman
Vielleicht wären die Testfälle klarer, wenn egrepsie für jede Eingabe separat ausgeführt würden, um jeweils den passenden Exit-Code zu erhalten: Probieren Sie es online aus! .
Handarbeit
3

Dies unter der Annahme, dass die Eingabe ein gültiges Ordnungsmuster ist. Wenn dies nicht der Fall ist, müssen Änderungen vorgenommen werden

JavaScript (Node.js) , 97 92 78 Byte

s=>("tsnr"[~~((n=(o=s.match(/(\d{1,2})(\D)/))[1])/10%10)-1?n%10:0]||'t')==o[2]

Probieren Sie es online!

Erläuterung

s=>
   ("tsnr"                                // all the options for ordinal - 4-9 will be dealt afterwards    
      [~~(                                //floor the result of the next expression
        (n=(                              //save the number (actually just the two right digits of it into n
          o=s.match(/(\d{1,2})(\D)/))[1]) //store the number(two digits) and the postfix into o (array)
        /10%10)-1                         //if the right most(the tenths digit) is not 1 (because one is always 'th')
          ?n%10:0]                        //return n%10 (where we said 0-3 is tsnr and afterwards is th
            ||'t')                        // if the result is undefined than the request number was between 4 and 9 therefor 'th' is required
    ==o[2]                                // match it to the actual postfix  

_____________________________________________________________________

Hafen von @Herman Lauenstein

JavaScript (Node.js) , 48 Byte

s=>/1.th|(^|[^1])(1st|2nd|3rd|[^1-3]th)/.test(s)

Probieren Sie es online!

DanielIndie
quelle
Wenn die Annahme reg Lösung auch sein kann***.
l4m2
Wenn nicht angenommen wird, dass es sich um / \ d * (st | nd | rd | th) / handelt, 1stabestehen Sie den Reg-Test. wenn angenommen, /1.th|(^|[^1])(1s|2n|3r|[^1-3]t)/Arbeit
l4m2
3

Python ,  56  53 Bytes

-3 Dank an (Verwenden Sie die eindeutige Buchstabeneinbeziehung anstelle der vorletzten Zeichengleichheit)

lambda v:'hsnrhhhhhh'[(v[-4:-3]!='1')*int(v[-3])]in v

Eine unbenannte Funktion.

Probieren Sie es online!

Wie?

Da alle Eingabe (hier v) garantiert die Form sein , \d*[st|nd|rd|th]können wir nur testen , ob ein Zeichen in besteht vdie wir dort sein zu erwarten , wenn es richtig wäre ( s, n, r, oder h, respectively) - das ist <getExpectedLetter>in v.

Die letzte Ziffer bestimmt normalerweise Folgendes:

v[-3]: 0 1 2 3 4 5 6 7 8 9
v[-2]: h s n r h h h h h h

... außer wenn die vorletzte Ziffer a ist 1, wenn alles mit enden sollte thund daher unser erwarteter Charakter sein muss h; dies zu bewerten wir ein Stück nehmen können (einen Index Fehler zu vermeiden , für die Eingänge mit nicht vorkommenden -4 th Charakter) v[-4:-3]. Da 0Karten hbereits vorhanden sind, können wir den gewünschten Effekt durch Multiplikation vor der Indizierung in erzielen 'hsnrhhhhhh'.

Jonathan Allan
quelle
st, nd, rd und th haben alle einen eindeutigen Buchstaben, so dass Sie nur testen können, ob er in der Zeichenfolge 53 Bytes vorkommt
Asone Tuhid
@AsoneTuhid schönes golf - danke!
Jonathan Allan
@AsoneTuhid - speicherte auch drei auf meine Gelee-Antwort, also doppelten Dank!
Jonathan Allan
3

Java 8, 54 51 Bytes

s->s.matches(".*1.th|(.*[^1])?(1s|2n|3r|[^1-3]t).")

Erläuterung:

Probieren Sie es online aus.

s->  // Method with String parameter and boolean return-type
  s.matches(".*1.th|(.*[^1])?(1s|2n|3r|[^1-3]t).")
     //  Validates if the input matches this entire regex

Javas String # -Matches werden implizit hinzugefügt ^...$.

Regex Erklärung:

^.*1.th|(.*[^1])?(1s|2n|3r|[^1-3]t).$
^                                          Start of the regex
 .*1.                                       If the number ends in 11-19:
     th                                      it must have a trailing th
       |                                    If not:
        (.*    )?                            Optionally it has leading digits,
           [^1]                              excluding a 1 at the end
                 (1s|2n|3r         .      followed by either 1st, 2nd, 3rd,
                          |[^1-3]t).      0th, 4th, 5th, ..., 8th, or 9th
                                    $   End of the regex
Kevin Cruijssen
quelle
2

Pyth, 49 60 Bytes SBCS

Js<2zK%J100I||qK11qK12qK13q>2z"th".?qz+J@c."dt8¸*£tÎðÎs"2J

Testsuite

SE hat einige nicht druckbare Dateien im Code (und in der folgenden Erläuterung) gefressen, diese sind jedoch im Link enthalten.

Erläuterung:
Js<2zK%J100I||qK11qK12qK13q>2z"th".?qz+J@c."dt8¸*£tÎðÎs"2J # Code
Js<2z                                                         # J= the integer in the input
     K%J100                                                   # K=J%100
           I||qJ11qJ12qJ13                                    # IF K is 11, 12, or 13:
                          q>2z"th"                            #  Print whether the end of the input is "th"
                                  .?                          # Otherwise:
                                    qz                        #  Print whether the input is equal to
                                      +J                      #   J concatenated with
                                        @                   J #    The object at the Jth modular index of
                                          ."dt8¸*£tÎðÎs"   #     The string "thstndrdthththththth"
                                         c                 2  #      Chopped into strings of length 2 as a list
Python 3 Übersetzung:
z=input();J=int(z[:-2]);K=J%100
if K==11or K==12or K==13:print(z[-2:]=="th")
else:print(z==str(J)+["thstndrdthththththth"[2*i:2*i+2] for i in range(10)][J%10])
hakr14
quelle
2

Python 2, 92 82 74 68 Bytes

-8 danke an Chas Brown
-6 danke an Kevin Cruijssen

lambda s:(a+'t'*10+a*8)[int(s[-4:-2]):][:1]==s[-2:-1]
a='tsnr'+'t'*6

Konstruiert eine große Folge von ths, sts, nds und rds für Endungen 00zu 99. Überprüfen Sie dann, ob es passt.

Oliver Ni
quelle
2

Retina , 35-31 Bytes

-4 Bytes dank @Asone Tuhid

Vielen Dank an @Leo für das Auffinden eines Fehlers

1.th|(^|[^1])(1s|2n|3r|[04-9]t)

Ausgänge 1für wahr und 0falsch. Dies setzt voraus , der Eingang in ordinal Format mit einem gültigen Suffix (Enden mit st, nd, rdoder th).

Probieren Sie es online!

Herman L
quelle
1

Jelly ,  25  22 Bytes

-3 Bytes dank einer Beobachtung in einem Kommentar von meinem Python-Eintrag.

ḣ-2VDṫ-’Ạ×ɗ/«4ị“snrh”e

Eine monadische Verbindung.

Probieren Sie es online! Oder sehen Sie sich die Testsuite an .

Wie?

ḣ-2VDṫ-’Ạ×ɗ/«4ị“snrh”e - Link: list of characters   e.g. "213rd" or "502nd" or "7th"
ḣ-2                    - head to index -2                "213"      "502"      "7"
   V                   - evaluate                         213        502        7
    D                  - cast to decimal list            [2,1,3]    [5,0,2]    [7]
     ṫ-                - tail from index -1                [1,3]      [0,2]    [7]
           /           - reduce with:                                          (no reduction since already length 1)
          ɗ            -   last 3 links as a dyad:                           
       ’               -     decrement (the left)           0         -1        x
        Ạ              -     all? (0 if 0, 1 otherwise)     0          1        x
         ×             -     multiply (by the right)        0          2        x
            «4         - minimum of that and 4              0          2        4
              ị“snrh”  - index into "snrh"                 'h'        'n'      'h'
                     e - exists in? (the input list)        0          1        1
Jonathan Allan
quelle
0

05AB1E , 24 Byte

0ìþR2£`≠*.•’‘vê₅ù•sèsáнQ

Probieren Sie es online! oder als Testsuite

Erläuterung

0ì                         # prepend 0 to input
  þ                        # remove letters
   R                       # reverse
    2£                     # take the first 2 digits
      `≠                   # check if the 2nd digit is false
        *                  # and multiply with the 1st digit
         .•’‘vê₅ù•         # push the string "tsnrtttttt"
                  sè       # index into this string with the number calculated
                    sáн    # get the first letter of the input
                       Q   # compare for equality
Emigna
quelle
0

Rubin , 42 39 Bytes

Lambda:

->s{s*2=~/1..h|[^1](1s|2n|3r|[4-90]t)/}

Probieren Sie es online!

Benutzereingabe:

p gets*2=~/1..h|[^1](1s|2n|3r|[4-90]t)/

Probieren Sie es online!

Streichhölzer:

  • 1(anything)(anything)h - 12th
  • (not 1)1s - (1st )
  • (not 1)2n - (2nd )
  • (not 1)3r - (3rd )

Da [^1]( not 1) nicht mit dem Anfang einer Zeichenfolge übereinstimmt, wird die Eingabe dupliziert, um sicherzustellen, dass ein Zeichen vor dem letzten steht.


Ruby -n , 35 Bytes

p~/1..h|([^1]|^)(1s|2n|3r|[4-90]t)/

Probieren Sie es online!

Dieselbe Idee wie oben, aber anstatt die Zeichenfolge zu duplizieren, entspricht dies auch dem Anfang der Zeichenfolge ( ^).

Asone Tuhid
quelle
0

Excel, 63 Bytes

=A1&MID("thstndrdth",MIN(9,2*RIGHT(A1)*(MOD(A1-11,100)>2)+1),2)

(MOD(A1-11,100)>2)kehrt zurück, FALSEwenn A1endet mit 11-13

2*RIGHT(A1)*(MOD(A1-11,100)>2)+1kehrt , 1wenn es in 11- 13und 3, 5, 7usw. Andernfalls

MIN(9,~)ändert alle Rückgaben 9in 9, um die thaus der Zeichenfolge zu ziehen

MID("thstndrdth",MIN(~),2)aus den ersten Zügen thfür die Eingänge der Endung 11- 13, stfür 1, ndfür 2, rdfür 3, und die letzte thfür etwas höher.

=A1&MID(~) Stellt die ursprüngliche Nummer vor die Ordnungszahl.


Als Wiki posten, da ich nicht der Autor davon bin. ( Quelle )

Engineer Toast
quelle
0

Wolfram Language (Mathematica) , 122 Bytes

Im Gegensatz zu den meisten anderen Antworten hier wird hier tatsächlich false zurückgegeben, wenn die Eingabe kein "gültiges Ordnungsmuster" ist, sodass sie bei Eingaben wie "3a23rd", "monkey" oder "╚§ +!" Korrekt false zurückgibt. Ich denke, das funktioniert für den gesamten Satz möglicher Eingabezeichenfolgen.

StringMatchQ[((d=DigitCharacter)...~~"1"~(e=Except)~d~~(e["1"|"2"|"3",d]~~"th")|("1st"|"2nd"|"3rd"))|(d...~~"1"~~d~~"th")]

Probieren Sie es online!

Kelly Lowder
quelle
0

Wolfram Language (Mathematica) , 65 59 Bytes

SpokenString@p[[#]]~StringTake~{5,-14}&@@ToExpression@#==#&

Probieren Sie es online!

Natürlich verfügt Mathematica über eine integrierte (wenn auch nicht dokumentierte) Funktion zum Konvertieren in eine Ordnungszahl. Quelle .

(für die 65-Byte-Version: dementsprechend scheint es, dass v9 und früher keinen Aufruf benötigen Speak so dass möglicherweise weitere Bytes werden können)

Schauen Sie sich auch die Antwort von KellyLowder für eine nicht eingebaute Version an.

user202729
quelle
0

PHP, 60 Bytes

langweilig: regexp nochmal die kürzeste lösung

<?=preg_match("/([^1]|^)(1st|2nd|3rd|\dth)$|1\dth$/",$argn);

leere Ausgabe für falsch, 1 für wahr.

Laufen Sie als Pipe mit -nFoder probieren Sie es online aus . (TiO aus Bequemlichkeitsgründen als Funktion eingewickelt)

Titus
quelle
0

x86-Maschinencode, 65 Byte

00000000: 31c0 4180 3930 7cfa 8079 0161 7ef4 8079  1.A.90|..y.a~..y
00000010: ff31 7418 31db 8a19 83eb 308a 9300 0000  .1t.1.....0.....
00000020: 0031 db43 3851 010f 44c3 eb0a 31db 4380  .1.C8Q..D...1.C.
00000030: 7901 740f 44c3 c374 736e 7274 7474 7474  y.t.D..tsnrttttt
00000040: 74                                       t

Versammlung:

section .text
	global func
func:					;the function uses fastcall conventions
					;ecx=first arg to function (ptr to input string)
	xor eax, eax			;reset eax to 0
	read_str:
		inc ecx			;increment ptr to string

		cmp byte [ecx], '0'
		jl read_str		;if the char isn't a digit, get next digit
		cmp byte [ecx+1], 'a'
		jle read_str		;if the char after the digit isn't a letter, get next digit
		cmp byte [ecx-1], '1'
		je tens 		;10-19 have different rules, so jump to 'tens'
		xor ebx, ebx		;reset ebx to 0
		mov bl, byte [ecx]  	;get current digit and store in bl (low byte of ebx)
		sub ebx, 0x30		;convert ascii digit to number
		mov dl, [lookup_table+ebx] ;get correct ordinal from lookup table
		xor ebx, ebx		;reset ebx to 0
		inc ebx			;set ebx to 1
		cmp byte [ecx+1], dl	;is the ordinal correct according to the lookup table?
		cmove eax, ebx		;if the ordinal is valid, set eax (return reg) to 1 (in ebx)
		jmp end			;jump to the end of the function and return

		tens:
		xor ebx, ebx		;reset ebx to 0
		inc ebx			;set ebx to 1
		cmp byte [ecx+1], 't'	;does it end in th?
		cmove eax, ebx		;if the ordinal is valid, set eax (return reg) to 1 (in ebx)

	end:
	ret				;return the value in eax
section .data
	lookup_table db 'tsnrtttttt'

Probieren Sie es online!

Logern
quelle
-1

Perl-kompatibler regulärer Ausdruck, 29 Byte

1.th|(?<!1)(1s|2n|3r)|[4-90]t

Wir akzeptieren thnach jeder "Teen" -Nummer oder nach jeder anderen Ziffer als 1..3. Für 1..3 verwenden wir eine negative Lookbehind zu akzeptieren st, ndoder rdnur , wenn sie nicht mit vorangestelltem1 .

Testprogramm

#!/usr/bin/bash

ok=(✓ ❌)

for i
do grep -Pq '1.th|(?<!1)(1s|2n|3r)|[4-90]t' <<<"$i"; echo $i ${ok[$?]}
done 

Ergebnisse

1st ✓
1th ❌
2nd ✓
2th ❌
3rd ✓
3th ❌
4st ❌
4th ✓
11th ✓
11st ❌
12nd ❌
12th ✓
13th ✓
13rd ❌
112nd ❌
112th ✓
21nd ❌
32nd ✓
33rd ✓
21th ❌
21st ✓
11st ❌
111199231923819238198231923213123909808th ✓
Toby Speight
quelle