Напишіть функцію, яка повертає минулий час даного дієслова


14

Виклик

Напишіть функцію, яка бере аргумент, який є дієсловом, і повертає минуле час дієслова. (Припустимо, що дієслово є регулярним)

Минулий час

Примітка: вважайте y ні приголосним, ні на голосним.

Зазвичай саме додавання edпісля закінчення дієслова робить минуле час дієслова.

Наприклад: jumpjumped, askasked

Однак є й інші правила.

  • Якщо останній символ даного дієслова є e, просто додайте d.

    Наприклад: loveloved, movemoved

  • Якщо дієслово закінчується приголосним + y, то змініть yна iта додайте ed.

    Наприклад: studystudied, crycried

  • Однак якщо дієслово закінчується голосним + y, тоді просто додайте ed.

    Наприклад: 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 Тому я сказав "(Припустимо, що дієслово є регулярним)"
JiminP

@ Quandary: Не зовсім правда ... дивіться відповідь Велізарія .
Саймон

Відповіді:


6

sed, 76 символів

Чи розглядає сценарій sed як функцію цієї проблеми?

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

4

Математика 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"}

Ви не думаєте, що пошук словника якось обманює? :-)
Саймон,

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

Scala 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-до списку => до функції:

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

Рубі, 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"

Використовуйте синтаксис лямбда Ruby 1.9, f=->(x){...}щоб отримати коротший код. Також aeiouyІМХО має бути постійним.
Hauleth


0

Пітон - 147

def f (v): T, x, m = 'aeiou', "ed", v [-1]; повернути [[[v + x, v + m + x] [v [-2] в T і m і v [-3] не в T], [v + x, v [: - 1] + "ied"] [v [-2] не в T]] [m == 'y'], v + "d "] [m == 'e']  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.