Controllo della stringa ordinale


17

Descrizione:

Data una stringa come input, controlla se è un numero ordinale valido in inglese o meno. Se è valido, restituire un valore di verità, altrimenti restituire un valore di falsa. (Suggerito da @Arnauld. Grazie. Anche da @JoKing)

Per gli utenti che vogliono conoscere i numeri ordinali vai qui:

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

Ingressi possibili:

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

Questa è una sfida del codice golf , quindi il codice più breve in ogni lingua sarà il vincitore.

Esempi:

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

Dal momento che molte persone hanno posto la domanda se l'input sarà o meno solo stringhe valide:

Tutti gli input saranno sempre validi. cioè saranno sotto forma di stringa e consisteranno in una cifra (o numero di cifre) insieme a uno dei quattro suffissi:

st, nd, rd,th


Puoi chiarire le regole dei numeri ordinali? O almeno metti un link a quali regole stai seguendo.
qwr

Sono regole normali. Non ho cambiato nulla. Ma grazie per l'input, ho aggiunto un link
Muhammad Salman,

@Jonathan Allan I numeri ordinali partono da 1st, non esistono ordinali negativi - english.stackexchange.com/questions/309713/…
Oliver Ni

@JonathanAllan OP dice "L'input sarà un modello ordinale valido." il che significa che non ci sono aspetti negativi
Oliver Ni,

2
Dici che gli input saranno sempre validi ma penso che un termine migliore sarebbe ben formato . Sia il 12 che il 12 sono ben formati, ma solo il primo è valido .
David Conrad,

Risposte:


3

Utilità Bash + GNU , 54

La corrispondenza del Regex sembra essere una strada semplice da percorrere. Sono abbastanza sicuro che questa espressione potrebbe essere abbreviata di più:

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

Ingresso da STDIN. Output come codice di ritorno della shell - 0 è verità e 1 è falsa.

Provalo online!


Che cosa ? questo non sta producendo la risposta corretta.
Muhammad Salman,

@MuhammadSalman Questo perché è una suite di test. Dai un'occhiata ai codici di uscita per 1ste 1th.
Dennis,

egrepè in grado di eseguire test di addizione e primalità (in unario), quindi penso che tu possa farne una risposta egrep.
Dennis,

Mi dispiace ma il mio bash fa schifo perché non ho idea di nulla. Mi sono annoiato, quindi ho usato un correttore differenziale per verificare la differenza tra input e output. Vedo il tuo punto. Quindi ho una domanda ora @Dennis: Bash ha dei booleani?
Muhammad Salman,

Forse i casi di test sarebbero più chiari se egrepfossero eseguiti separatamente per ciascun input per ottenere il codice di uscita corrispondente per ciascuno: provalo online! .
arte

3

questo presuppone che l'input sia un modello ordinale valido. in caso contrario, è necessario apportare modifiche

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]

Provalo online!

Spiegazione

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  

_____________________________________________________________________

porto di @Herman Lauenstein

JavaScript (Node.js) , 48 byte

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

Provalo online!


Se anche la soluzione del registro delle ipotesi può essere***.
l4m2

Se non si assume che sia / \ d * (st | nd | rd | th) / input, 1stapassare il test reg; se assunto, /1.th|(^|[^1])(1s|2n|3r|[^1-3]t)/lavora
l4m2

3

Python ,  56  53 byte

-3 grazie a (usa l'inclusione di lettere univoche anziché la penultima uguaglianza dei caratteri)

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

Una funzione senza nome.

Provalo online!

Come?

Poiché tutti ingresso (qui v) è garantito per essere della forma \d*[st|nd|rd|th]possiamo solo verificare se un carattere esiste in vcui ci aspettiamo di essere lì se fosse corretto ( s, n, r, o h, rispettivamente) - cioè <getExpectedLetter>in v.

L'ultima cifra di solito determina questo:

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

... tranne quando la penultima cifra è un 1, quando tutto dovrebbe finire con the quindi il nostro carattere previsto deve essere h; per valutare ciò possiamo prendere una porzione (per evitare che si verifichi un errore di indice per input senza carattere -4 ° ) v[-4:-3]. Dal momento che le 0mappe sono hgià in grado di ottenere l'effetto desiderato utilizzando la moltiplicazione prima dell'indicizzazione in 'hsnrhhhhhh'.


st, nd, rd e th hanno tutti una lettera univoca, quindi puoi solo verificare se si verifica nella stringa 53 byte
Asone Tuhid

@AsoneTuhid nice golf - grazie!
Jonathan Allan,

@AsoneTuhid - ho anche salvato tre sulla mia risposta Jelly, quindi raddoppia i ringraziamenti!
Jonathan Allan,

3

Java 8, 54 51 byte

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

Spiegazione:

Provalo 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

La stringa String # di Java aggiunge implicitamente ^...$.

Spiegazione 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

2

Pyth, 49 60 byte SBCS

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

Suite di test

SE ha mangiato alcuni non stampabili nel codice (e nella spiegazione di seguito) ma sono presenti nel collegamento.

Spiegazione:
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
Traduzione di 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])

2

Python 2, 92 82 74 68 byte

-8 grazie a Chas Brown
-6 grazie a Kevin Cruijssen

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

Costruisce una grande serie di ths, sts, nds, e rds per terminazioni 00a 99. Quindi controlla se corrisponde.


2

Retina , 35 31 byte

-4 byte grazie a @Asone Tuhid

Grazie a @Leo per aver trovato un bug

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

Output 1per vero e 0falso. Questo presuppone l'input è in formato ordinale con un suffisso valido (estremità con st, nd, rdo th).

Provalo online!




1

Gelatina ,  25  22 byte

-3 byte grazie a un'osservazione fatta in un commento fatto dalla mia voce su Python.

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

Un collegamento monadico.

Provalo online! Oppure vedi la suite di test .

Come?

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


0

05AB1E , 24 byte

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

Provalo online! o come una suite di test

Spiegazione

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

0

rubino , 42 39 byte

Lambda:

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

Provalo online!

Input dell'utente:

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

Provalo online!

gli incontri:

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

Poiché [^1]( not 1) non corrisponde all'inizio di una stringa, l'input viene duplicato per assicurarsi che ci sia un carattere prima dell'ultimo.


Rubino -n , 35 byte

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

Provalo online!

Stessa idea di cui sopra ma invece di duplicare la stringa, corrisponde anche all'inizio della stringa ( ^).


0

Excel, 63 byte

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

(MOD(A1-11,100)>2)ritorna FALSEquando A1termina con 11-13

2*RIGHT(A1)*(MOD(A1-11,100)>2)+1restituisce 1se è in 11- 13e 3, 5, 7, ecc. altrimenti

MIN(9,~)cambia i ritorni sopra 9in in 9per estrarre thla stringa

MID("thstndrdth",MIN(~),2)estrae il primo thper gli input che terminano con 11- 13, stper 1, ndper 2, rdper 3e l'ultimo thper qualcosa di superiore.

=A1&MID(~) antepone il numero originale all'ordinale.


Pubblicare come wiki poiché non sono l'autore di questo. ( Fonte )


0

Wolfram Language (Mathematica) , 122 byte

A differenza della maggior parte delle altre risposte qui, questo in realtà restituirà false quando l'input non è un "modello ordinale valido", quindi restituirà correttamente false in input come "3a23rd", "monkey" o "╚§ +!". Quindi penso che questo funzioni per l'intero set di possibili stringhe di input.

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

Provalo online!


0

Wolfram Language (Mathematica) , 65 59 byte

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

Provalo online!

Naturalmente Mathematica ha un built-in (anche se non documentato) per la conversione in numero ordinale. fonte .

(per la versione a 65 byte: in base a ciò sembra che v9 e precedenti non necessitino di una chiamata Speak prima, quindi potrebbe essere possibile salvare qualche altro byte)

Controlla anche la risposta di KellyLowder per una versione non integrata .


0

PHP, 60 byte

noioso: regexp ancora una volta la soluzione più breve

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

output vuoto per falsy, 1per verità.

Esegui come pipe -nFo provalo online . (TiO avvolto come funzione per comodità)


0

codice macchina x86, 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

Montaggio:

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'

Provalo online!


-1

Espressione regolare compatibile con Perl, 29 byte

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

Accettiamo thdopo qualsiasi numero "teenager" o dopo qualsiasi cifra diversa da 1..3. Per 1..3, usiamo un lookbehind negativo di accettare st, ndo rdsolo quando non preceduta da 1.

Programma di test

#!/usr/bin/bash

ok=(✓ ❌)

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

risultati

1st ✓
1th ❌
2nd ✓
2th ❌
3rd ✓
3th ❌
4st ❌
4th ✓
11th ✓
11st ❌
12nd ❌
12th ✓
13th ✓
13rd ❌
112nd ❌
112th ✓
21nd ❌
32nd ✓
33rd ✓
21th ❌
21st ✓
11st ❌
111199231923819238198231923213123909808th ✓
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.