序数字符串检查


17

说明:

给定一个字符串作为输入,请检查它是否是英文的有效序数。如果有效,则返回真实值,否则返回虚假值。(由@Arnauld建议。谢谢。也由@JoKing提供)

对于想了解序数的用户,请点击此处:

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

可能的输入:

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

这是一场高尔夫挑战赛代码,因此每种语言中最短的代码将成为赢家。

例子 :

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

由于很多人问有关输入是否仅是有效字符串的问题:

所有输入将始终有效。也就是说,它们将采用字符串形式,由一个数字(或数字位数)以及四个后缀之一组成:

stndrdth


您能阐明序数规则吗?或至少放置一个指向您遵循的规则的链接。
qwr

这是正常规则。我什么都没改变。但是,感谢您的输入,我添加了一个链接
Muhammad Salman

@Jonathan艾伦·序数从开始1st,负序不存在- english.stackexchange.com/questions/309713/...
奥利弗镍

@JonathanAllan OP说“输入将是有效的序数模式。” 这意味着没有负面影响
Oliver Ni

2
您说这些输入将始终是有效的,但我认为可以更好地形成一个术语。第十二名和第十二名的格式正确,但只有前者有效
戴维·康拉德

Answers:


3

Bash + GNU实用程序,54

正则表达式匹配似乎是一种简单的方法。我很确定这个表达式可以进一步缩短:

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

来自STDIN的输入。输出为shell返回码-0为真,1为假。

在线尝试!


什么 ?这没有输出正确的答案。
穆罕默德·萨勒曼 Muhammad Salman)

@MuhammadSalman那是因为它是一个测试套件。看看的退出代码1st1th
丹尼斯

egrep能够进行加性和素性测试(一元),因此我认为您可以将其作为egrep答案。
丹尼斯

抱歉,我的拳头很烂,因为我根本不知道里面有什么东西。我很无聊,所以使用差异检查器检查输入和输出之间的差异。我明白你的意思了。所以我现在有一个问题@Dennis:Bash有布尔值吗?
穆罕默德·萨勒曼

如果egrep将每个输入单独执行以获取每个输出的匹配退出代码,则测试用例可能会更加清楚:在线尝试!
manatwork '18

3

这是在假设输入为有效序数模式的情况下得出的。如果不是这种情况,则需要进行更改

JavaScript(Node.js)97 92 78字节

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

在线尝试!

说明

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  

_____________________________________________________________________

@Herman Lauenstein的港口

JavaScript(Node.js),48字节

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

在线尝试!


如果假设reg解决方案也可以是***.
l4m2

如果未假设它是/ \ d *(st | nd | rd | th)/输入,则1sta通过reg测试;如果假设的话,/1.th|(^|[^1])(1s|2n|3r|[^1-3]t)/工作
l4m2,18年

3

蟒蛇 56  53字节

-3感谢(使用唯一的字母包含而不是倒数第二个字符相等)

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

未命名的函数。

在线尝试!

怎么样?

由于所有的输入(这里v)是保证是这样的形式\d*[st|nd|rd|th],我们可以只测试一个字符是否存在于v我们预期在那里,如果它是正确的(snr,或h,分别) -这是<getExpectedLetter>in v

最后一位数字通常决定了这一点:

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

...除非倒数第二个数字是a 1,否则所有th字符都应以结尾,因此我们的预期字符必须为h;要对此进行评估,我们可以进行切片(以避免对于 -4 字符的输入发生索引错误)v[-4:-3]。由于已经0映射到,h我们可以在索引到之前使用乘法来获得所需的效果'hsnrhhhhhh'


st,nd,rd和th都有一个唯一的字母,因此您可以测试它是否出现在字符串53个字节中
Asone Tuhid18年

@AsoneTuhid不错的高尔夫-谢谢!
乔纳森·艾伦

@AsoneTuhid-在果冻答案上也保存了三个,所以加倍感谢!
乔纳森·艾伦

3

Java 8,54 51字节

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

说明:

在线尝试。

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

Java的String#matches隐式添加^...$

正则表达式说明:

^.*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字节 SBCS

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

测试套件

SE在代码中(以及下面的说明中)吃了一些无法打印的内容,但它们存在于链接中。

说明:
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翻译:
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

蟒蛇2,92 82 74 68字节

-8感谢查斯·布朗
-6感谢凯文·克鲁伊森

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

构造ths,sts,nds和rds 的大字符串作为结尾0099。然后检查是否匹配。


2

视网膜35 31字节

-4个字节,感谢@Asone Tuhid

感谢@Leo发现错误

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

输出1true和0false。这假定输入是在序格式与有效的后缀(端部用stndrdth)。

在线尝试!




1

果冻 25  22 字节

-3个字节,这得益于对我的Python条目的注释中的观察。

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

单子链接。

在线尝试!或查看测试套件

怎么样?

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

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

在线尝试! 或作为测试套件

说明

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

红宝石 42 39字节

Lambda:

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

在线尝试!

用户输入:

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

在线尝试!

火柴:

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

由于[^1]not 1)与字符串的开头不匹配,因此重复输入以确保最后一个字符之前有一个字符。


红宝石 -n,35字节

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

在线尝试!

与上面相同的想法,但是除了复制字符串之外,它还匹配字符串(^)的开头。


0

Excel,63个字节

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

(MOD(A1-11,100)>2)FALSEA111- 结尾时返回13

2*RIGHT(A1)*(MOD(A1-11,100)>2)+1返回1如果它在11- 13357,等。除此以外

MIN(9,~)改变上述任何回报99th从字符串

MID("thstndrdth",MIN(~),2)提取第一个th11- 13stfor 1ndfor 2rdfor 3和结尾的输入,最后一个th以更高的值输入。

=A1&MID(~) 将原始编号附加到序号上。


由于我不是这个作者,所以发布为Wiki。(来源


0

Wolfram语言(Mathematica),122字节

与此处的大多数其他答案不同,当输入不是“有效的序数模式”时,此方法实际上将返回false,因此在诸如“ 3a23rd”,“ monkey”或“╚§+!”之类的输入中将正确返回false。因此,我认为这适用于整个可能的输入字符串集。

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

在线尝试!


0

Wolfram语言(Mathematica)65 59字节

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

在线尝试!

当然,Mathematica具有内置的(尽管未记录)可转换为序数。来源

(对于65字节的版本:据此看来,v9及更高版本不需要调用 Speak在之前,因此可能可以节省更多的字节)

另外,请查看非内置版本的KellyLowder 答案


0

PHP,60个字节

无聊:regexp再次是最短的解决方案

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

空输出虚假, 1真实。

与管道一起运行-nF在线尝试。(为方便起见,TiO被包裹为功能)


0

x86机器代码,65字节

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

部件:

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'

在线尝试!


-1

与Perl兼容的正则表达式,29个字节

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

我们接受th任何“青少年”数字之后,或除1..3。以外的任何数字。对于1..3,我们使用负回顾后接受stnd或者rd只有当没有前面1

测试程序

#!/usr/bin/bash

ok=(✓ ❌)

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

结果

1st ✓
1th ❌
2nd ✓
2th ❌
3rd ✓
3th ❌
4st ❌
4th ✓
11th ✓
11st ❌
12nd ❌
12th ✓
13th ✓
13rd ❌
112nd ❌
112th ✓
21nd ❌
32nd ✓
33rd ✓
21th ❌
21st ✓
11st ❌
111199231923819238198231923213123909808th ✓
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.