删除不明确的复数!


21

编程非常严格。您不能告诉程序“输出香蕉计数”,而必须告诉它print(bananas)

但是,当您这样做时,最终会遇到一个问题:您不知道事先拥有多少个香蕉,因此您不知道是否使用复数。

有时,程序员会走懒惰的路。他们只检查而不是检查there are X banana(s)

但这很丑陋,因此我们需要一个程序来解决此问题。

方法)

要删除字符串中的歧义复数,请执行以下步骤:

  1. 将空格上的字符串分成单词列表。

  2. 对于以结尾的每个单词(s),请执行以下操作:

    • 如果前面的字是aan1one,除去(s)在字的结尾。
    • 否则,如果该字是第一个字在字符串中或前述字不是aan1one,替换(s)在与字的末尾s
  3. 将单词列表重新组合成一个字符串,以保留原始空格。

例子)

让我们来一个字符串there's a banana(s) and three apple(s)

首先,我们将字符串分成单词列表: ["there's", "a", "banana(s)", "and", "three", "apple(s)"]

第二步,我们使用两个以(s)banana(s)和结尾的单词apple(s)

之前的单词banana(s)a,因此我们删除了(s)banana。这个词之前apple(s)three的,所以我们改(s)s,因此变得apples

我们现在有["there's", "a", "banana", "and", "three", "apples"]。将列表重新加入,我们得到there's a banana and three apples。这是我们的最终结果。

挑战

创建一个程序或函数,该程序或函数采用任意合理格式的模糊字符串,并返回该字符串的明确版本。

您可以假定该字符串不包含任何换行符,制表符或回车符。

我忘了指定是否对空间或空间(即,是否组织分裂了okay then两个空格应该是["okay", "then"]["okay", "", "then"]张贴的挑战时,那么你可以假设分裂两种形式)。

测试用例)

Input                                         -> Output
there are two banana(s) and one leprechaun(s) -> there are two bananas and one leprechaun
there's a banana(s) and three apple(s)        -> there's a banana and three apples
apple(s)                                      -> apples
one apple(s)                                  -> one apple
1 banana(s)                                   -> 1 banana
banana                                        -> banana
preserve    original      whitespace(s)       -> preserve    original      whitespaces
11 banana(s)                                  -> 11 bananas
an apple(s)                                   -> an apple
this is a te(s)t                              -> this is a te(s)t
I am a (s)tranger(s)                          -> I am a (s)tranger

计分

由于这是,因此字节数最少的提交将获胜!


这个问题已经被沙盒化了
LyricLy

apple(s)测试用例应该屈服apples吗?挑战指出,Otherwise, if the word is the first word in the string . . . replace the (s) at the end of the word with s.我注意到apples在前三个修订版的沙箱中产生了这种情况,但在第四次修订版中发生了变化。
fireflame241

@ fireflame241在编写规则的第二稿时,我要做的是使字符串的开头保持不变。我后来更改了该规则,但没有更改测试用例。接得好。
LyricLy

测试用例建议:There's a single banana(s)-> There's a single bananas
乔纳森·艾伦

1
@JonathanAllan你不能。我将添加一些测试用例。
LyricLy

Answers:


6

数学,151个 148字节的

StringReplace[j=" ";k=Except@j;j<>j<>#<>j,j~~a:k...~~s:j..~~w:k..~~"(s)"~~j:>{j,a,s,w,If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""]}<>j]~StringTake~{3,-2}&

说明

j=" ";k=Except@j

设置j为空白字符。设置k为模式“ not j”(=非空格字符)。

j<>j<>#<>j

在输入之前添加两个空格,并将一个添加到输入。

j~~a:k...~~s:j..~~w:k..~~"(s)"~~j

对于与模式匹配的子字符串:

  1. 一个空格,后跟一个
  2. 一个零长度或更长的子字符串,仅由非空白字符(量化符)(称为a)组成,后跟
  3. 一个长度为一或更长的子字符串,仅由空格字符(称为s)组成,后跟
  4. 一个长度为一或更长的子字符串,仅由非空白字符(单词)(称为w)组成,后跟
  5. 字符串"(s)",后跟
  6. 空格
如果[FreeQ [a,“ a” |“ an” |“ 1” |“ one”],“ s”,“”]]

如果a不是奇异词之一,则求值为"s",否则为""

StringReplace[..., ... :>{j,a,s,w,If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""]}<>j]

替换与匹配模式jaswIf[FreeQ[a,"a"|"an"|"1"|"one"],"s",""],和j接合在一起。

... ~StringTake~{3,-2}

从位置3移到位置-2(1索引;负索引从末尾开始计数)。这是因为我们在开头添加了三个空格。


3
为什么不使用内置函数删除复数S?
Thomas Weller

5

Python 3,94个字节

lambda s,r=re.sub:r(r"\(s\)( |$)","s",r(r"\b(an?|1|one)(\s+)(.+)\(s\)",r"\1\2\3",s))
import re

在线尝试!

-4个字节感谢i cri每个人(我认为这是可以接受的)


@JonathanAllan固定,谢谢。
HyperNeutrino

1
__import__不可能更短...是的,比常规的短4个字节import re
完全人类

@icrieverytim恩,你是对的(尽管只有3个字节),谢谢
HyperNeutrino


@icrieverytim ._。不错哦。谢谢!
HyperNeutrino


4

Mathematica,313个字节

(Table[If[StringLength@z[[i]]>3&&StringTake[z[[i]],-3]=="(s)",z[[i]]=StringDrop[z[[i]],-3];t=1;While[z[[i-t]]=="",t++];If[FreeQ[{"a","an","1","one"},z[[i-t]]],z[[i]]=z[[i]]<>"s"]],{i,2,Length[z=StringSplit[#," "]]}];If[StringTake[z[[1]],-3]=="(s)",z[[1]]=StringDrop[z[[1]],-3];z[[1]]=z[[1]]<>"s"];StringRiffle@z)&

3

Perl 5,43 +1(-p)= 44字节

s/\b((one|1|an?) +)?\S+\K\(s\)\B/"s"x!$1/ge

匹配(s)单词末尾的每一个,用!$1(1或0)esses 代替。


2

Pyth-53个字节

完全遵循该算法。

K+kczdjdt.e?q"(s)"gb_2+<b_3*\s!}@Ktk[\a"an""one"\1)bK

在这里在线尝试


1
失败there are two banana(s) and one leprechaun(s)(后面两个空格one)。原始空格保留,但leprechaun(s)忽略它one之前的空格。
LyricLy

1
@LyricLy您尚未在OP中明确说明这一点。有两个空格(使用“方法的(1)”部分的“将空格上的字符串拆分为单词列表”)之间oneleprechaun(s)
Jonathan Allan

2

果冻 52 51  49 字节

果冻没有一个正则表达式原子

Ṫ
Ñ;”s
Ṫḣ-3
UṪw“)s(”⁼1
“µḣ⁴µuʠg*»ḲċḢ‘×Ç‘
⁶;ḲÇĿ2ƤK

接受字符串的完整程序(如果使用多行或包含引号,则使用Python格式)并输出输出。

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

怎么样?

Ṫ - Link 1, tail: two words (list of lists)
Ṫ - tail

Ñ;”s - Link 2, tail and replace last three chars with an 's': two words (list of lists)
Ñ    - call the next link (3) as a monad
  ”s - literal 's'
 ;   - concatenate

Ṫḣ-3 - Link 3, tail and remove the last three chars: two words (list of lists)
Ṫ    - tail
  -3 - literal minus three
 ḣ   - head from index (1-indexed and modular)

UṪw“)s(”⁼1 - Link 4, tail ends with "(s)"?: two words (list of lists)
U          - upend (reverse each word)
 Ṫ         - tail
   “)s(”   - literal [')', 's', '('] - that is "(s)" reversed
  w        - index of first sublist equal to that or 0 if not found
         1 - literal one
        ⁼  - equal?

“µḣ⁴µuʠg*»ḲċḢ‘×Ç‘ - Link 5, categorise: two words (list of lists)
“µḣ⁴µuʠg*»        - compression of string "a 1" + word " an" + word " one"
          Ḳ       - split on spaces = ["a", "1", "an", "one"]
            Ḣ     - head (the first word)
           ċ      - count occurrences (of head in the list - either 0 or 1)
             ‘    - increment
               Ç  - call the last link (4) as a monad - i.e. f(two words)
              ×   - multiply
                ‘ - increment - so we have: 1 for ["1", "blah"],
                  -             2 for ["blah", "blah(s)"] or 3 for ["1", "blah(s)"]

⁶;ḲÇĿ2ƤK - Main link: list of characters, the string
⁶        - literal space character
 ;       - concatenate (place a space at the beginning as we want to inspect pairs)
  Ḳ      - split on spaces (giving an empty list at the start)
     2Ƥ  - for all infixes of length two:
    Ŀ    -   call the link at the given index as a monad:
   Ç     -     call the last link (5) as a monad
       K - join the result with spaces
         - implicit print

我很好奇您为什么使用单独的链接。这样是否可以防止从原始列表中删除该元素?
HyperNeutrino

不,我需要弄清楚这对人的尾巴……编写代码注释,也许一旦您看到高尔夫球就可以发现它。
乔纳森·艾伦

啊好吧。谢谢,一旦有评论(或之前),我将尽力发现高尔夫!
HyperNeutrino

因此,链接1、2和3都尾部,而链接5选择要调用的链接并使用它来链接Ŀ,但是我看不到在链接4内尾部链接的简短方法,但有可能。甚至还有可能将链接4的尾部插入其中!
乔纳森·艾伦

@HyperNeutrino我认为它Ŀ可以调用第一个链接,这就是为什么它是一个链接。
Erik the Outgolfer '17


1

Perl 5,56 +1(-p)= 57字节

s/\b(an?|1|one) +\S+\K\(s\)(?= |$)//g;s/\(s\)( |$)/s$1/g

在线尝试!


1
不在测试用例上,但是我认为这对失败a hel(s)lo
尼尔

如测试用例中所提供的那样,它可以正常工作。它在我的TIO链接中测试用例的底部附近。
Xcali

好吧,我只需要a hel(s)lo添加到测试用例中,然后也许您就可以修复您的代码...
Neil

0

JavaScript(ES6),88 87字节

a=>a.replace(/(\S+)( +)(\S+)\(s\)/g,(m,f,s,w)=>f+s+w+(/^(a|an|1|one)$/.exec(f)?'':'s'))

解释即将推出。


1
您可以\s根据“您可以假设该字符串不包含换行符,制表符或回车符” 将其替换为``。
SuperStormer

失败“这是一个te”。您可以通过添加(\s|$)到正则表达式的末尾进行修复。
伯乔拉修(Birjolaxew)

在“苹果”上也失败。固定在这个TIO
Birjolaxew

谢谢@Birjolaxew,当我可以的时候会编辑更改...
XavCo7

0

JavaScript(ES6),84个字节

s=>s.replace(/((^|\S+ +)\S+)\(s\)(?!\S)/g,(_,a)=>a+(/^(1|an?|one) /.test(a)?'':'s'))

这是重新安排最后一部分的一种有趣方法,可悲的是,它的长度要长2个字节:

s=>s.replace(/((^|\S+ +)\S+)\(s\)(?!\S)/g,(_,a)=>a+'s'.slice(/^(1|an?|one) /.test(a)))

0

JavaScript(SpiderMonkey),82字节

s=s.replace(/(\S+ +(\S+))\(s\)\B/g,(_,a)=>a+("s"[+/^(1|one|an?)\b/i.test(a)]||""))

在线尝试!

78字节版本(较不健壮)

s=s.replace(/(\S+ +(\S*))\(s\)/g,(_,a)=>a+("s"[+/^(1|one|an?)/i.test(a)]||""))

这是ETHproductions的修改版本(我没有50个代表)。

说明

  • /(\S+ +(\S+))\(s\)/g-要寻找的实际模式(amount object(s)
  • (_,a)=>a- _是所有变量,a(\S+ +(\S+))
  • "s"[+/^(1|one|an?)/i.test(a)]||"" -无需切片数组,只需创建一个虚拟数组并获取索引(+/.../.test返回一个数字)
    • 应该"s"[+/^(1|one|an?)/i.test(a)]返回undefinedtrue1用于测试)返回""
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.