Viết hàm trả về thì quá khứ của động từ đã cho


14

Thử thách

Viết hàm lấy một đối số là động từ và trả về thì quá khứ của động từ. (Giả sử rằng động từ là thường xuyên)

Thì quá khứ

Lưu ý: coi y là phụ âm cũng không phải nguyên âm.

Thông thường, chỉ cần thêm edsau khi kết thúc động từ làm cho thì quá khứ của động từ.

Vd: jumpjumped, askasked

Tuy nhiên, có những quy tắc khác.

  • Nếu ký tự cuối cùng của động từ đã cho là e, chỉ cần thêm d.

    Vd: loveloved, movemoved

  • Nếu động từ kết thúc bằng phụ âm + y, sau đó đổi ythành ivà thêm ed.

    Vd: studystudied, crycried

  • Tuy nhiên, nếu động từ kết thúc bằng nguyên âm + y, thì chỉ cần thêm ed.

    Vd: playplayed, staystayed

  • Nếu một động từ được kết thúc bằng một nguyên âm và một phụ âm, sau đó viết phụ âm thêm một lần nữa và thêm ed.

    Vd: stopstopped, planplanned

  • Tuy nhiên, nếu một động từ được kết thúc bằng nhiều nguyên âm + một phụ âm hoặc nguyên âm đơn + nhiều phụ âm, thì chỉ cần thêm ed.

    Vd: looklooked, jumpjumped

Có nhiều quy tắc hơn nhưng chúng ta chỉ quan tâm đến các quy tắc. Ví dụ: theo quy tắc trên, visitvisitted.

Người chiến thắng

Vì đây là mã golf, mã ngắn nhất trả về chính xác các thì quá khứ sẽ thắng.

Ví dụ (JS, 127)

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


Bây giờ đó là một thử thách tốt.
FUZxxl

nghịch đảo gốc! hấp dẫn! Tôi sẽ cố gắng thử khi tôi trở về nhà :)
DallaRosa

Bất kỳ giải pháp nào ngắn hơn 1800 ký tự đều không chính xác (động từ bất quy tắc).
Quandary

@Quandary Đó là lý do tại sao tôi nói '(Giả sử động từ là thường xuyên)'
JiminP

@Quandary: Không hoàn toàn đúng ... xem câu trả lời của Belisarius .
Simon

Câu trả lời:


6

sed, 76 ký tự

Liệu một kịch bản sed được tính là một chức năng cho vấn đề này?

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

4

Toán học 43 ký tự

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

Sử dụng:

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

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

Cũng thế:

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

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

Bạn không nghĩ rằng tra cứu từ điển là hơi gian lận? :-)
Simon

3
@Simon dứt khoát là không. WordData là một phần của ngôn ngữ :)
Tiến sĩ belisarius

3

Groovy - 111 ký tự

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 ký tự):

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

Tôi chắc chắn rằng nó có thể được cải thiện.


2

C - 120 119 ký tự

Trong kiểu C điển hình, hàm f cập nhật bộ đệm chuỗi tại chỗ, giả sử rằng người gọi đã dành đủ không gian cho tối đa ba ký tự phụ. Đối số thứ hai nên được đưa ra là 0. Việc khai báo biến trạng thái toàn cục lđược bao gồm trong tổng số ký tự.

#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;
}

Giải thích: Hàm lặp qua các ký tự theo cách đệ quy. Đối số thứ hai imã hóa ba ký tự trước đó là phụ âm ở ba bit dưới cùng của nó. Ở cuối chuỗi, nếu i==5sau đó ba ký tự cuối cùng là một phụ âm, nguyên âm và phụ âm, và do đó, ký tự cuối cùng phải được nhân đôi. Tương tự, nếu bit 1 ichỉ ra rằng ký tự thứ hai đến cuối cùng là phụ âm và ký tự cuối cùng là 'y', thì 'y' được thay thế bằng 'i'.


1

Scala 199 273 ký tự

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"}

Cầu nguyện:

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

Cách tiếp cận đầu tiên của tôi dài hơn nhiều, bằng cách di chuyển if-other-cascade sang một danh sách => sang một hàm:

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")))}

Có lẽ cách tiếp cận là thú vị. Bị thoái hóa và giải thích:

// 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 ký tự

Có lẽ có thể nhỏ hơn.

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

Sử dụng:

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

Sử dụng cú pháp lambda Ruby 1.9 f=->(x){...}để có được mã ngắn hơn. Ngoài ra aeiouyIMHO nên là một hằng số.
Hauleth

0

Poop - 72 ký tự

f[s]s^6pow>4<<last&8*(/"ed""id""eid"/|out|flush)+rep'y'1-2-3"aeiou"ord#s

0

Con trăn - 147

def f (v): T, x, m = 'aeiou', "ed", v [-1]; return [[[v + x, v + m + x] [v [-2] trong T và m và v [-3] không ở T], [v + x, v [: - 1] + "ied"] [v [-2] không ở T]] [m == 'y'], v + "d "] [m == 'e']  
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.