Escreva uma função que retorne o tempo passado do verbo determinado

14

Desafio

Escreva uma função que use um argumento que seja um verbo e retorne o tempo passado do verbo. (Suponha que o verbo seja regular)

Pretérito

Nota: considere y como nem consoante nem vogal.

Normalmente, apenas a adição edapós o final do verbo torna o pretérito do verbo.

Ex: jumpjumped, askasked

No entanto, existem outras regras.

  • Se o último caractere do verbo fornecido for e, basta adicionar d.

    Ex: loveloved, movemoved

  • Se o verbo terminar com uma consoante + y, altere ypara ie adicione ed.

    Ex: studystudied, crycried

  • No entanto, se o verbo terminar com uma vogal + y, basta adicionar ed.

    Ex: playplayed, staystayed

  • Se um verbo terminar com uma vogal e uma consoante, escreva a consoante mais uma vez e adicione ed.

    Ex: stopstopped, planplanned

  • No entanto, se um verbo terminar com várias vogais + uma consoante ou vogal única + várias consoantes, basta adicionar ed.

    Ex: looklooked, jumpjumped

Existem mais regras, mas vamos cuidar apenas das regras. Por exemplo, de acordo com a regra acima, visitvisitted.

Vencedora

Como esse é o código de golfe, o código mais curto que retorna corretamente os tempos passados ​​vence.

Exemplo (JS, 127)

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

JiminP
fonte
Agora esse é um bom desafio.
FUZxxl
stemming inverso! interessante! Vou tentar dar uma chance quando eu chegar em casa de volta :)
Dallarosa
Qualquer solução com menos de 1800 caracteres está incorreta (verbos irregulares).
Quandary
@Quandary É por isso que eu disse '(Suponha que o verbo é regular)'
JiminP
@ Quandary: Não é bem verdade ... veja a resposta de Belisarius .
Simon

Respostas:

6

sed, 76 caracteres

Um script sed conta como uma função para esse problema?

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

Mathematica 43 chars

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

Uso:

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

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

Além disso:

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

{"bought", "ran", "swam"}
Dr. belisarius
fonte
Você não acha que uma consulta no dicionário é meio trapaceira? :-)
Simon
3
@Simon Definitivamente não. WordData é parte da linguagem :)
Dr. belisarius
3

Groovy - 111 caracteres

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
fonte
2

Perl 5 (82 caracteres):

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

Estou certo de que pode ser melhorado.

Prakash K
fonte
2

C - 120 119 caracteres

No estilo C típico, a função f atualiza um buffer de sequência, assumindo que o chamador tenha reservado espaço suficiente para até três caracteres extras. O segundo argumento deve ser dado como 0. A declaração da variável de estado global lestá incluída na contagem total de caracteres.

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

Explicação: A função repete os caracteres recursivamente. O segundo argumento icodifica quais dos três caracteres anteriores eram consoantes em seus três bits inferiores. No final da cadeia, se i==5os três últimos caracteres eram uma consoante, uma vogal e uma consoante e, portanto, o último caractere deve ser duplicado. Da mesma forma, se o bit 1 de iindicar que o penúltimo caractere era uma consoante e o último caractere é 'y', o 'y' é substituído por 'i'.

han
fonte
1

Scala 199 273 chars

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

Invocação:

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

Minha primeira abordagem foi muito mais longa, movendo a cascata if-else para uma lista => para uma função:

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

Talvez a abordagem seja interessante. Degolfado e explicado:

// 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")
  ))}
Usuário desconhecido
fonte
0

Ruby, 101 caracteres

Provavelmente pode ser menor.

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"
LBg
fonte
Use a sintaxe lambda do Ruby 1.9 f=->(x){...}para obter um código mais curto. aeiouyIMHO também deve ser uma constante.
Hauleth
0

Cocô - 72 caracteres

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

Python - 147

def f (v): T, x, m = 'aeiou', "ed", v [-1]; return [[[[v + x, v + m + x]] [v [-2] em T e m e v [-3] não em T], [v + x, v [: - 1] + "ied"] [v [-2] não em T]] [m == 'y'], v + "d "] [m == 'e']  
Homem de codificação
fonte