Schreiben Sie eine Funktion, die die Vergangenheitsform des angegebenen Verbs zurückgibt

14

Herausforderung

Schreiben Sie eine Funktion, die ein Argument verwendet, das ein Verb ist, und die Vergangenheitsform des Verbs zurückgibt. (Angenommen, das Verb ist regulär)

Vergangenheitsform

Hinweis: Betrachten Sie y weder als Konsonanten noch als Vokale.

Normalerweise wird durch einfaches Hinzufügen ednach dem Ende des Verbs die Vergangenheitsform des Verbs erstellt.

Bsp .: jumpjumped, askasked

Es gibt jedoch andere Regeln.

  • Wenn das letzte Zeichen des angegebenen Verbs ist e, fügen Sie einfach hinzu d.

    Bsp .: loveloved, movemoved

  • Wenn das Verb mit einem Konsonanten + endet y, ändern Sie es yzu iund fügen Sie es hinzu ed.

    Bsp .: studystudied, crycried

  • Wenn das Verb jedoch mit einem Vokal + endet y, fügen Sie einfach hinzu ed.

    Bsp .: playplayed, staystayed

  • Wenn ein Verb mit einem Vokal und einem Konsonanten endet, schreiben Sie den Konsonanten noch einmal und fügen Sie hinzu ed.

    Bsp .: stopstopped, planplanned

  • Wenn ein Verb jedoch mit mehreren Vokalen + einem Konsonanten oder einem einzelnen Vokal + mehreren Konsonanten endet, fügen Sie einfach hinzu ed.

    Bsp .: looklooked, jumpjumped

Es gibt mehr Regeln, aber wir sollten uns nur um die Regeln kümmern. Zum Beispiel laut der obigen Regel visitvisitted.

Gewinner

Da dies Codegolf ist, gewinnt der kürzeste Code, der die Vergangenheitsform korrekt zurückgibt.

Beispiel (JS, 127)

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

JiminP
quelle
Das ist eine schöne Herausforderung.
FUZxxl
invers stemming! interessant! Ich werde versuchen, es zu versuchen, wenn ich nach Hause
komme
Jede Lösung, die kürzer als 1800 Zeichen ist, ist falsch (unregelmäßige Verben).
Quandary
@Quandary Deshalb habe ich gesagt '(Angenommen, das Verb ist regulär)'
JiminP
@Quandary: Nicht ganz richtig ... siehe die Antwort von Belisarius .
Simon

Antworten:

6

sed, 76 zeichen

Zählt ein sed-Skript als Funktion für dieses Problem?

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

Mathematica 43 Zeichen

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

Verwendung:

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

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

Ebenfalls:

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

{"bought", "ran", "swam"}
Dr. belisarius
quelle
Sie glauben nicht, dass eine Wörterbuchsuche ein bisschen schummelt? :-)
Simon
3
@ Simon Definitiv nein. WordData ist Teil der Sprache :)
Dr. Belisarius
3

Groovy - 111 Zeichen

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']
Armand
quelle
2

Perl 5 (82 Zeichen):

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

Ich bin sicher, dass es verbessert werden kann.

Prakash K
quelle
2

C - 120 119 Zeichen

Im typischen C-Stil aktualisiert die Funktion f einen vorhandenen Zeichenfolgenpuffer, vorausgesetzt, der Aufrufer hat genügend Platz für bis zu drei zusätzliche Zeichen reserviert. Das zweite Argument sollte mit 0 angegeben werden. Die Deklaration der globalen Statusvariablen list in der Gesamtzahl der Zeichen enthalten.

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

Erläuterung: Die Funktion durchläuft die Zeichen rekursiv. Das zweite Argument ikodiert, welche der drei vorhergehenden Zeichen in den unteren drei Bits Konsonanten waren. Wenn i==5die letzten drei Zeichen am Ende der Zeichenfolge ein Konsonant, ein Vokal und ein Konsonant waren, muss das letzte Zeichen dupliziert werden. Wenn Bit 1 von iangibt, dass das vorletzte Zeichen ein Konsonant war und das letzte Zeichen 'y' ist, wird das 'y' durch 'i' ersetzt.

han
quelle
1

Scala 199 273 Zeichen

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

Aufruf:

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

Mein erster Ansatz war viel länger, indem ich die if-else-Kaskade auf eine Liste => auf eine Funktion verschob:

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

Vielleicht ist der Ansatz interessant. Entgolfet und erklärt:

// 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")
  ))}
Benutzer unbekannt
quelle
0

Ruby, 101 Zeichen

Kann wohl kleiner sein.

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

Verwendung:

f("try")  #=> "tried"
f"call"   #=> "called"
LBg
quelle
Verwenden Sie die Lambda-Syntax f=->(x){...}von Ruby 1.9 , um kürzeren Code zu erhalten. Auch aeiouymeiner Meinung nach sollte eine Konstante sein.
Hauleth
0

Poop - 72 Zeichen

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

Python - 147

def f (v): T, x, m = 'aeiou', "ed", v [-1]; gib [[[v + x, v + m + x] [v [-2] in T und m zurück und v [-3] nicht in T], [v + x, v [: - 1] + "ied"] [v [-2] nicht in T]] [m == 'y'], v + "d "] [m == 'e']  
Codierung Mann
quelle