เขียนฟังก์ชั่นที่คืนค่าอดีตกาลของคำกริยาที่กำหนด


14

ท้าทาย

เขียนฟังก์ชันที่รับอาร์กิวเมนต์ซึ่งเป็นคำกริยาและคืนค่าอดีตกาลของคำกริยา (สมมติว่าคำกริยาเป็นปกติ)

อดีตกาล

หมายเหตุ: พิจารณา y เป็นพยัญชนะหรือสระ

โดยปกติเพียงเพิ่มedหลังจากสิ้นสุดคำกริยาทำให้กาลที่ผ่านมาของคำกริยา

เช่นjumpjumped, askasked

อย่างไรก็ตามมีกฎอื่น ๆ

  • ถ้าตัวอักษรตัวสุดท้ายของคำกริยาให้เป็นเพียงแค่เพิ่มed

    เช่นloveloved, movemoved

  • ถ้าเป็นคำกริยาจะจบลงด้วยการ + พยัญชนะyแล้วเปลี่ยนyไปและเพิ่มied

    เช่นstudystudied, crycried

  • แต่ถ้าเป็นคำกริยาจะจบลงด้วยการสระ + แล้วเพียงแค่เพิ่มyed

    เช่นplayplayed, staystayed

  • หากคำกริยาลงท้ายด้วยสระและพยัญชนะให้เขียนพยัญชนะอีกครั้งแล้วเพิ่ม edหากคำกริยาจะจบลงด้วยการสระและพยัญชนะแล้วเขียนพยัญชนะอีกครั้งหนึ่งและเพิ่ม

    เช่นstopstopped, planplanned

  • แต่ถ้าเป็นคำกริยาจะจบลงด้วยการสระหลาย + พยัญชนะหรือสระเดี่ยว + edหลายพยัญชนะแล้วเพียงแค่เพิ่ม

    เช่นlooklooked, jumpjumped

มีกฎมากกว่า แต่ให้ใส่ใจกฎข้างต้นเท่านั้น ตัวอย่างเช่นตามกฎข้างต้นvisitvisitted

ผู้ชนะ

เนื่องจากนี่คือรหัสกอล์ฟรหัสที่สั้นที่สุดที่ส่งกลับกาลเวลาในอดีตชนะอย่างถูกต้อง

ตัวอย่าง (JS, 127)

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


นี่เป็นความท้าทายที่ดี
FUZxxl

เกิดการผกผัน! ! ที่น่าสนใจ ผมจะพยายามให้ลองเมื่อฉันได้รับกลับบ้าน :)
DallaRosa

การแก้ปัญหาใด ๆ ที่สั้นกว่า 1800 ตัวอักษรนั้นไม่ถูกต้อง (คำกริยาที่ผิดปกติ)
Quandary

@Quandary นั่นเป็นเหตุผลที่ผมบอกว่า '(สมมติว่าคำกริยาเป็นปกติ)
JiminP

@Quandary: ไม่เป็นความจริงทีเดียว ... ดูคำตอบของเบลิซาเรี
Simon

คำตอบ:


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 เป็นส่วนหนึ่งของภาษา :)
Dr. 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 - 120 119 ตัวอักษร

ในสไตล์ 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

สกาล่า 199 273ตัวอักษร

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"

ใช้ไวยากรณ์ lambda Ruby 1.9 f=->(x){...}เพื่อรับรหัสที่สั้นกว่า นอกจากนี้ยังaeiouyIMHO ควรจะมีอย่างต่อเนื่อง
Hauleth


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.