Scrivi una funzione che ritorni al passato del verbo dato


14

Sfida

Scrivi una funzione che accetta un argomento che è un verbo e restituisce il passato del verbo. (Supponiamo che il verbo sia regolare)

Tempo passato

Nota: considerare y né consonante né vocale.

Normalmente, l'aggiunta eddopo la fine del verbo rende il tempo passato del verbo.

Es: jumpjumped, askasked

Tuttavia, ci sono altre regole.

  • Se l'ultimo carattere del verbo dato è e, basta aggiungere d.

    Es: loveloved, movemoved

  • Se il verbo termina con una consonante + y, cambia yin ie aggiungi ed.

    Es: studystudied, crycried

  • Tuttavia, se il verbo termina con una vocale + y, quindi basta aggiungere ed.

    Es: playplayed, staystayed

  • Se un verbo termina con una vocale e una consonante, allora scrivi la consonante ancora una volta e aggiungi ed.

    Es: stopstopped, planplanned

  • Tuttavia, se un verbo termina con più vocali + una consonante o vocale singola + più consonanti, quindi aggiungi ed.

    Es: looklooked, jumpjumped

Ci sono più regole ma ci preoccupiamo solo delle regole sopra. Ad esempio, secondo la regola sopra, visitvisitted.

Vincitore

Dato che si tratta di code golf, vince il codice più breve che restituisce correttamente i tempi passati.

Esempio (JS, 127)

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


Questa è una bella sfida.
FUZxxl,

inversa stemming interessante! Proverò a provare quando torno a casa :)
DallaRosa,

Qualsiasi soluzione più corta di 1800 caratteri non è corretta (verbi irregolari).
Quandary

@Quandary Ecco perché ho detto '(Supponi che il verbo sia regolare)'
JiminP

@Quandario: non del tutto vero ... vedi la risposta di Belisario .
Simon,

Risposte:


6

sed, 76 caratteri

Uno script sed conta come una funzione per questo problema?

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

4

Mathematica 43 caratteri

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

Uso:

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

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

Anche:

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

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

Non pensi che la ricerca di un dizionario stia tradendo? :-)
Simon,

3
@Simon Sicuramente no. WordData fa parte della lingua :)
Dr. belisarius,

3

Groovy - 111 caratteri

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 caratteri):

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

Sono sicuro che può essere migliorato.


2

C - 120 119 caratteri

In tipico stile C, la funzione f aggiorna un buffer di stringa in atto, supponendo che il chiamante abbia riservato spazio sufficiente per un massimo di tre caratteri aggiuntivi. Il secondo argomento dovrebbe essere dato come 0. La dichiarazione della variabile di stato globale lè inclusa nel conteggio totale dei caratteri.

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

Spiegazione: La funzione scorre ripetutamente i caratteri. Il secondo argomento icodifica quale dei tre caratteri precedenti erano consonanti nei suoi tre bit inferiori. Alla fine della stringa, se i==5poi gli ultimi tre caratteri erano una consonante, una vocale e una consonante, e quindi l'ultimo carattere deve essere duplicato. Allo stesso modo, se il bit 1 di iindica che il penultimo carattere era una consonante e l'ultimo carattere è 'y', allora 'y' è sostituito da 'i'.


1

Scala 199 273 caratteri

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

Invocazione:

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

Il mio primo approccio è stato molto più lungo, spostando if-else-cascade in un elenco => in una funzione:

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

Forse l'approccio è interessante. Degolfato e spiegato:

// 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

Rubino, 101 caratteri

Probabilmente può essere più piccolo.

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

Uso:

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

Utilizzare la sintassi lambda di Ruby 1.9 f=->(x){...}per ottenere un codice più breve. Anche aeiouyIMHO dovrebbe essere una costante.
Hauleth,

0

Cacca - 72 caratteri

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

0

Python - 147

def f (v): T, x, m = 'aeiou', "ed", v [-1]; return [[[v + x, v + m + x] [v [-2] in T e m e v [-3] non in T], [v + x, v [: - 1] + "ied"] [v [-2] non in T]] [m == 'y'], v + "d "] [m == 'e']  
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.