编写一个函数,返回给定动词的过去式


14

挑战

编写一个函数,该函数接受一个作为动词的自变量,并返回该动词的过去式。(假设动词是规则的)

过去式

注意:认为y既不是辅音也不是元音。

通常,仅ed在动词结尾之后加一个即可使动词的过去时。

例如:jumpjumpedaskasked

但是,还有其他规则。

  • 如果给定动词的最后一个字符是e,只需加d

    例如:lovelovedmovemoved

  • 如果动词以辅音+结尾y,则y改为i,并加ed

    例如:studystudiedcrycried

  • 但是,如果动词以元音+结尾y,则只需添加即可ed

    例如:playplayedstaystayed

  • 如果动词以元音和辅音结尾,则再写一次辅音,然后添加ed

    例如:stopstoppedplanplanned

  • 但是,如果一个动词以多个元音+一个辅音或一个元音+多个辅音结尾,则只需添加即可ed

    例如:looklookedjumpjumped

还有更多规则,但让我们只关注规则。例如,根据上述规则,visitvisitted

优胜者

由于这是代码高尔夫球,因此正确返回过去时态的最短代码将获胜。

范例(JS,127)

function f(x){return x.replace(/([^aeiouy])y$/,'$1i').replace(/([^aeiouy][aeiou])([^aeiouy])$/,'$1$2$2').replace(/e$/,'')+'ed'}


现在,这是一个不错的挑战。
FUZxxl 2011年

逆茎!有趣!我回到家时会尝试一下:)
DallaRosa

少于1800个字符的任何解决方案都是不正确的(不规则动词)。
困惑

@Quandary这就是为什么我说“(假设动词是规则的)”的原因
JiminP 2011年

@Quandary:不太正确...请参阅Belisarius的答案
西蒙

Answers:


6

sed,76个字符

sed脚本是否可算作解决此问题的函数?

s/\([^aeiou]\)y$/\1i/
s/\([^aeiou][aeiou]\)\([^aeiouy]\)$/\1\2\2/
s/e\?$/ed/

4

Mathematica 43个字符

f=WordData[#,"InflectedForms","List"][[1]]&

用法:

f /@ {"call", "try", "use", "wash", "play", "stop", "look"}

{"called", "tried", "used", "washed", "played", "stopped", "looked"}

也:

f /@ {"buy", "run", "swim"}

{"bought", "ran", "swam"}

您不认为字典查找有点欺骗吗?:-)
Simon

3
@Simon绝对不会。WordData是语言的一部分:)
belisarius博士,

3

Groovy-111个字符

v={it==~'[aeiou]'};p={s->r=s[0..-2];a=s[-1];b=v s[-2];(a=='e'?r:a=='y'?!b?r+'i':s:v(s[-3])|!b|v(a)?s:s+a)+'ed'}

assert ['jump', 'ask', 'love', 'move', 'study', 'cry', 'play', 'stay', 'stop', 'plan', 'look'].collect { p(it) } == ['jumped', 'asked', 'loved', 'moved', 'studied', 'cried', 'played', 'stayed', 'stopped', 'planned', 'looked']

2

Perl 5(82个字符):

sub f{$_=pop;$C='[^aeiouy]';s/($C)y$/$1i/;s/($C[aeiou])($C)$/$1$2$2/;s/e?$/ed/;$_}

我相信它可以改善。


2

C - 120119个字符

在典型的C样式中,函数f会在适当的位置更新字符串缓冲区,假设调用方已为最多三个额外的字符保留了足够的空间。第二个参数应为0。全局状态变量的声明l包含在总字符数中。

#include <stdio.h>
#include <string.h>

l;void f(b,i)char*b;{*b?f(b+1,i/2+4*!strchr("aeiouy",l=*b)):(i-5?*--b=l=='y'&i/2?'i':l:(*b=l),strcpy(b+=l!='e',"ed"));}

int main()
{
  char b[10000];
  while (gets(b)) {
    f(b,0);
    puts(b);
  }
  return 0;
}

说明:该函数以递归方式遍历字符。第二个自变量i编码前三个字符中的哪三个是其后三位的辅音。在字符串的末尾,如果i==5最后三个字符是辅音,元音和辅音,则必须复制最后一个字符。类似地,如果的位1 i表示倒数第二个字符是辅音,而最后一个字符为“ y”,则将“ y”替换为“ i”。


1

Scala 199273个字符

def v(c:Char)="aeiouy" contains c
def p(o:String)={val s=o.reverse
if(s(0)=='e')o+"d"else
if(!v(s(1))&& s(0)=='y')o.replaceAll("y$","ied")else
if(!v(s(0))&& v(s(1))&& !v(s(2)))o+s(0)+"ed"else
o+"ed"}

调用:

val li = List ("move", "cry", "plan", "play", "look")
li map p

我的第一种方法是更长的时间,方法是将if-else-cascade移到list =>到函数:

type S=String
def f(l:List[(Boolean,S)]):S=if(l(0)._1)l(0)._2 else f(l.tail)
def v(c:Char)="aeiouy" contains c
def c(o:S)={val s=o.reverse
f(List((s(0)=='e',o+"d"),(!v(s(1))&& s(0)=='y',o.replaceAll("y$","ied")),(!v(s(0))&& v(s(1))&& !v(s(2)),o+s(0)+"ed"),(true,o+"ed")))}

也许这种方法很有趣。脱轨并解释:

// just for shortening
type S=String
/* take a list of Booleans and Strings, and return early
   if a Boolean is true. This approach would work, 
   if there where much more conditions, I guess.
*/
def doFirst (list: List[(Boolean, S)]): S =
  if (list(0)._1) list(0)._2 else doFirst (list.tail)
// vocal - is it a vocal
def v(c:Char)="aeiouy" contains c
// here is the key function
def toPast(o:S)={
  // reversing the String allows easy access to the last elements, 
  // without considering how long the string is.
  val s=o.reverse
  doFirst (List (
    (s(0)=='e', o+"d"),
    (!v(s(1)) && s(0)=='y', o.replaceAll("y$","ied")),
    (!v(s(0)) && v(s(1)) && !v(s(2)), o+s(0)+"ed"),
    (true, o+"ed")
  ))}

0

Ruby,101个字符

可能会更小。

def f x;x.sub(/([^aeiouy])y$/,'\1i').sub(/([^aeiouy][aeiou])([^aeiouy])$/,'\1\2\2').sub(/e$/,'')+'ed';end

用法:

f("try")  #=> "tried"
f"call"   #=> "called"

使用Ruby 1.9 lambda语法f=->(x){...}可获得较短的代码。此外aeiouy恕我直言应该是一个常数。
Hauleth 2012年


0

Python-147

def f(v):T,x,m ='aeiou',“ ed”,v [-1];在T和m中返回[[[v + x,v + m + x] [v [-2] and v [-3] not in T],[v + x,v [:-1] +“ ied”] [v [-2] not in T]] [m =='y'],v +“ d “] [m =='e']  
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.