Sprawdzanie ciągów porządkowych

17

Opis:

Biorąc pod uwagę ciąg znaków, sprawdź, czy jest to poprawna liczba porządkowa w języku angielskim, czy nie. Jeśli jest poprawny, zwróć wartość prawdy, w przeciwnym razie zwróć wartość fałszu. (Sugerowane przez @Arnauld. Dzięki. Również przez @JoKing)

Dla użytkowników, którzy chcą wiedzieć o liczbach porządkowych, przejdź tutaj:

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

Możliwe dane wejściowe:

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

Jest to wyzwanie dla golfistów, więc zwycięzcą będzie najkrótszy kod w każdym języku.

Przykłady:

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

Ponieważ wiele osób zadało pytanie, czy dane wejściowe będą prawidłowe, czy nie:

Wszystkie dane wejściowe zawsze będą ważne. tzn. będą miały postać ciągu i będą składać się z cyfry (lub liczby cyfr) wraz z jednym z czterech sufiksów:

st, nd, rd,th

Muhammad Salman
źródło
Czy potrafisz wyjaśnić zasady liczb porządkowych? Lub przynajmniej umieść link do zasad, których przestrzegasz.
qwr
Są to normalne zasady. Nic nie zmieniłem. Ale dzięki za wkład, dodałem link
Muhammad Salman
@Jonathan Allan Liczby porządkowe zaczynają się od 1st, nie istnieją ujemne porządki - polish.stackexchange.com/questions/309713/…
Oliver Ni
@JathanathanAllan OP mówi: „Dane wejściowe będą prawidłowymi wzorcami porządkowymi”. co oznacza brak negatywów
Oliver Ni
2
Mówisz, że dane wejściowe zawsze będą ważne, ale myślę, że lepszy termin byłby dobrze sformułowany . Zarówno 12., jak i 12. są dobrze uformowane, ale tylko pierwsza z nich jest ważna .
David Conrad,

Odpowiedzi:

3

Narzędzia Bash + GNU , 54

Dopasowywanie wyrażeń regularnych wydaje się prostą drogą. Jestem prawie pewien, że to wyrażenie można skrócić bardziej:

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

Dane wejściowe ze STDIN. Wyjście jako kod powrotu powłoki - 0 to prawda, a 1 to falsey.

Wypróbuj online!

Cyfrowa trauma
źródło
Co ? to nie daje poprawnej odpowiedzi.
Muhammad Salman
@MuhammadSalman To dlatego, że jest to zestaw testowy. Spójrz na kody wyjścia dla 1sti 1th.
Dennis
egrepjest zdolny do dodawania i testowania pierwotności (jednostronnie), więc myślę, że możesz zrobić z tego odpowiedź egrep.
Dennis
Przykro mi, ale mój bash jest do bani, bo nie mam pojęcia o czymś. Nudzę się, więc użyłem sprawdzania różnic, aby sprawdzić różnicę między wejściem a wyjściem. Rozumiem co masz na myśli. Więc mam teraz jedno pytanie @Dennis: Czy Bash ma booleany?
Muhammad Salman
Może przypadki testowe byłyby bardziej wyraźne, gdyby egrepbyły wykonywane osobno dla każdego wejścia, aby uzyskać pasujący kod wyjścia dla każdego: Wypróbuj online! .
manatwork
3

zakłada się, że dane wejściowe są prawidłowym wzorem porządkowym. jeśli nie, należy wprowadzić zmiany

JavaScript (Node.js) , 97 92 78 bajtów

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

Wypróbuj online!

Wyjaśnienie

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  

_____________________________________________________________________

port @Herman Lauenstein

JavaScript (Node.js) , 48 bajtów

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

Wypróbuj online!

DanielIndie
źródło
Jeśli założeniem reg ***.
regu
Jeśli nie założono, że to / \ d * (st | nd | rd | th) / input, należy 1staprzejść test reg; jeśli założono, /1.th|(^|[^1])(1s|2n|3r|[^1-3]t)/praca
14m2
3

Python ,  56  53 bajtów

-3 dzięki (użyj unikalnego włączenia liter zamiast przedostatniej równości postaci)

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

Funkcja bez nazwy.

Wypróbuj online!

W jaki sposób?

Ponieważ wszystkie wejścia (tutaj v) jest gwarancją formularza \d*[st|nd|rd|th]możemy tylko testy czy postać istnieje w vktórym spodziewamy się tam, jeśli to były prawidłowe być ( s, n, r, lub h, odpowiednio) - to jest <getExpectedLetter>in v.

Ostatnia cyfra zwykle określa to:

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

... z wyjątkiem sytuacji, gdy przedostatnia cyfra to a 1, kiedy wszystko powinno się kończyć, tha zatem naszym oczekiwanym znakiem musi być h; ocena tego możemy wziąć kawałek (w celu uniknięcia błędu indeksu występujących na wejściach z bez -4 th znaków) v[-4:-3]. Od 0map do hjuż możemy osiągnąć pożądany efekt za pomocą mnożenia przed indeksowaniem do 'hsnrhhhhhh'.

Jonathan Allan
źródło
st, nd, rd i th mają unikalną literę, więc możesz po prostu sprawdzić, czy występuje w ciągu 53 bajtów
Asone Tuhid
@AsoneTuhid nice golf - dzięki!
Jonathan Allan
@AsoneTuhid - również zapisałem trzy na mojej odpowiedzi na galaretkę, więc podwój dzięki!
Jonathan Allan
3

Java 8, 54 51 bajtów

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

Wyjaśnienie:

Wypróbuj online.

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

Ciąg # dopasowań języka Java niejawnie dodaje ^...$.

Wyjaśnienie Regex:

^.*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
źródło
2

Pyth, 49 60 bajtów SBCS

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

Zestaw testowy

SE zjadł kilka niedrukowalnych elementów w kodzie (i w poniższym wyjaśnieniu), ale są one obecne w łączu.

Wyjaśnienie:
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
Tłumaczenie Python 3:
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
źródło
2

Python 2, 92 82 74 68 bajtów

-8 dzięki Chas Brown
-6 dzięki Kevin Cruijssen

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

Konstruuje duży ciąg ths, sts, nds i rds dla zakończeń 00do 99. Następnie sprawdza, czy pasuje.

Oliver Ni
źródło
2

Siatkówka , 35 31 bajtów

-4 bajty dzięki @Asone Tuhid

Dzięki @Leo za znalezienie błędu

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

Dane wyjściowe 1dla wartości true i 0false. Zakłada się, że dane wejściowe są w formacie porządkowym z poprawnym sufiksem (kończy się na st,nd , rdi th).

Wypróbuj online!

Herman L.
źródło
1

Perl 5 -n , 57 bajtów

/..$/;say$&eq(th,st,nd,rd,(th)x6)[$_%100-$_%10-10&&$_%10]

Wypróbuj online!

Xcali
źródło
1

Galaretka ,  25  22 bajtów

-3 bajty dzięki obserwacji dokonanej w komentarzu autorstwa mojego wpisu w Pythonie.

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

Link monadyczny.

Wypróbuj online! Lub zobacz zestaw testowy .

W jaki sposób?

ḣ-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
źródło
0

05AB1E , 24 bajty

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

Wypróbuj online! lub jako pakiet testowy

Wyjaśnienie

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
źródło
0

Rubin , 42 39 bajtów

Lambda:

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

Wypróbuj online!

Dane wejściowe użytkownika:

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

Wypróbuj online!

Mecze:

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

Ponieważ [^1]( not 1) nie pasuje do początku łańcucha, dane wejściowe są duplikowane, aby upewnić się, że przed ostatnim jest znak.


Rubin -n , 35 bajtów

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

Wypróbuj online!

Taki sam pomysł jak powyżej, ale zamiast duplikowania łańcucha, odpowiada to również początkowi łańcucha ( ^).

Asone Tuhid
źródło
0

Excel, 63 bajty

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

(MOD(A1-11,100)>2)zwraca, FALSEgdy A1kończy się na 11-13

2*RIGHT(A1)*(MOD(A1-11,100)>2)+1zwraca 1jeśli jest w 11-13 i 3, 5, 7itp. Inaczej

MIN(9,~) zmienia wszelkie zwroty powyżej 9 w, 9aby wyciągnąć thz łańcucha

MID("thstndrdth",MIN(~),2)wyciąga pierwszy thdla danych wejściowych kończących się na 11- 13, stfor 1, ndfor 2,rd na 3, a ostatni tho nic wyższego.

=A1&MID(~) wstawia oryginalny numer do liczby porządkowej.


Publikowanie jako wiki, ponieważ nie jestem autorem tego. ( Źródło )

Toast inżyniera
źródło
0

Wolfram Language (Mathematica) , 122 bajty

W przeciwieństwie do większości innych odpowiedzi tutaj, to faktycznie zwróci fałsz, gdy dane wejściowe nie są „prawidłowym wzorem porządkowym”, więc poprawnie zwróci fałsz przy danych wejściowych, takich jak „3a23rd”, „monkey” lub „╚§ +!”. Myślę więc, że działa to dla całego zestawu możliwych ciągów wejściowych.

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

Wypróbuj online!

Kelly Lowder
źródło
0

Wolfram Language (Mathematica) , 65 59 bajtów

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

Wypróbuj online!

Oczywiście Mathematica ma wbudowaną (choć nieudokumentowaną) funkcję konwersji na liczbę porządkową. Źródło .

(dla wersji 65-bajtowej: zgodnie z tym wydaje się, że wersja 9 i wcześniejsza nie potrzebuje wywoływania Speak wcześniejszego więc można zaoszczędzić trochę więcej bajtów)

Również sprawdzić KellyLowder za odpowiedź na wersję bez wbudowanego.

użytkownik202729
źródło
0

PHP, 60 bajtów

nudne: regexp jeszcze raz najkrótsze rozwiązanie

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

puste wyjście dla fałszowania, 1 dla prawdy.

Uruchom jako potok z -nFlub spróbuj online . (TiO zawinięty jako funkcja dla wygody)

Tytus
źródło
0

kod maszynowy x86, 65 bajtów

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

Montaż:

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'

Wypróbuj online!

Logern
źródło
-1

Wyrażenie regularne zgodne z Perl, 29 bajtów

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

Akceptujemy thpo każdym numerze „teen” lub po dowolnej cyfrze innej niż 1..3. Dla 1..3 używamy lookbehind negatywny, aby zaakceptować st, ndlub rdtylko wtedy, gdy nie poprzedza 1.

Program testowy

#!/usr/bin/bash

ok=(✓ ❌)

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

Wyniki

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
źródło