Conjugar un verbo turco

11

Entrada

  • verbo , una cadena que coincide con la expresión regular([a-pr-vyzıöüçğş]*[aeıioöuü][bcçdfgğhj-nprsştvyz]+|([a-pr-vyzıöüçğş]*[aeıioöuü]){2})(mak|mek)
  • plural , un valor verdadero o falso
  • persona , un número entero que tiene valor 1, 2 o 3
  • tiempo , un número entero que tiene valor 1, 2 o 3

Salida

La forma conjugada del verbo turco verbo , en persona st / nd / rd persona, plural si es plural es TRUEsingular y si no lo es, en

  • Si el tiempo es 1, el presente simple;
  • Si el tiempo es 2, el presente continuo;
  • Si el tiempo es 3, el futuro.

Reglas

Los verbos turcos se conjugan en tres elementos, que están en orden:

  • El tallo , formado al eliminar mako mekdesde el final del infinitivo;
  • El signo del tiempo , que es:

    • Por el presente simple:

      • -r si la raíz termina en una vocal;
      • -ir según las reglas de armonía vocal (ver más abajo) si la raíz contiene más de una sílaba (es decir, vocal), o es de uno de los siguientes verbos irregulares: almak, bilmek, bulmak, durmak, gelmek, görmek, kalmak, olmak, ölmek, sanmak, vermek, varmak, vurmak ;
      • -er de acuerdo con las reglas de armonía vocal si la raíz contiene una sílaba y no se encuentra en los verbos irregulares anteriores.
    • Para el presente continuo, -iyor , donde i cambia de acuerdo con las reglas de armonía vocal . Los tallos que terminan en una vocal caen esta vocal antes de agregar este sufijo, con lo cual el sufijo armoniza con la penúltima vocal de la palabra (garantizada por la expresión regular).

    • Para el futuro:
      • -ecek según las reglas de armonía vocal si la raíz termina en una consonante;
      • -yecek según las reglas de armonía de las vocales si la raíz termina en una vocal.
  • El sufijo personal para indicar el ejecutante de la acción, en todos los casos de acuerdo con las reglas de armonía vocal :

        |Singular|Plural|
    |---|--------|------|
    |1st|    -im |   -iz|
    |2nd|   -sin |-siniz|
    |3rd| (none) |  -ler|
    

    La k final del tiempo futuro se convierte en ğ antes de -im y -iz , por lo que, por ejemplo (almak, TRUE, 1, 3), cedería alacağız.

Reglas de armonía vocal

Las vocales turcas se dividen en dos grupos: atrás ( a ı o u) y frente ( e i ö ü) por el lugar donde se pronuncian en la boca. Los sufijos de una palabra cambian las vocales de acuerdo con las vocales de la raíz.

Todos los sufijos enumerados anteriormente que tienen i como vocal en su lugar usan:

  • si la última vocal antes del sufijo es ıo a(ambas vocales están atrás y sin redondear);
  • -i si la última vocal antes del sufijo es io e(ambas vocales son frontales y no redondeadas; observe aquí la distinción del turco entre I con puntos y sin puntos );
  • -u si la última vocal antes del sufijo es uo o(ambas vocales son posteriores y redondeadas); o
  • si la última vocal antes del sufijo es üo ö(ambas vocales son frontales y redondeadas).

Tome nota cuidadosa del presente sufijo continuo -yor . El iarmoniza, pero el ono cambia. Los sufijos personales armonizarán así con el o.

Todos los sufijos enumerados anteriormente que tienen e como vocal usan en su lugar:

  • -e si la última vocal antes del sufijo es una vocal frontal; o
  • -a si la última vocal antes del sufijo es una vocal inversa.

Verbos irregulares

Los verbos gitmek , tatmak , ditmek , gütmek y etmek cambian la final ta a dantes de cualquier final que comience con una vocal (que incluye todas las terminaciones en este desafío). Cualquier verbo que termine en -etmek también cambia el ta a d, y agrega -er para el presente simple (aunque esto no es así para los otros verbos).

Casos de prueba

gütmek, FALSE, 1, 2 -> güdüyorum
almak, TRUE, 3, 3 -> alacaklar
boğmak, TRUE, 2, 1 -> boğarsınız
ölmek, FALSE, 3, 1 -> ölür
boyamak, TRUE, 1, 2 -> boyuyoruz
affetmek, FALSE, 2, 1 -> affedersin
söylemek, TRUE, 3, 1 -> söylerler
söylemek, FALSE, 3, 2 -> söylüyor
söylemek, FALSE, 1, 3 -> söyleyeceğim
EMBLEMA
fuente
¿Podría proporcionar un caso de prueba para la -etmekregla?
Arnauld
@Arnauld Hecho. Al hacerlo, descubrí que cometí un error en la especificación, que he agregado a la sección "verbos irregulares".
EMBLEMA
Esto podría funcionar con muchos más casos de prueba, ya que la especificación es bastante compleja.
Dave
@Dave Agregué 3 más, lo que me llevó bastante tiempo en dispositivos móviles. Agregaré aún más más tarde.
EMBLEMA

Respuestas:

4

Javascript (ES6), 466 456 451 446 bytes

(v,p,w,t)=>(R=g=>g.exec(s),T=r=>s=s.slice(0,-1)+r,Z=s=>s.replace(/\d/g,c=>l=['ıuiü'[(n='aıoueiöü'.search(l))>>1],'ae'[n>>2]][c]),(s=v.slice(k=l=0,-3)).replace(/[aıoueiöü]/g,c=>(L=l,l=c,k++)),(R(/^(gi|ta|di|gü)t$/)||(R(/et$/)&&(k=1)))&&T`d`,((E=R(/[aıoueiöü]$/))&&t==2?(l=L,T``):s)+Z([(E?'':k<2&!R(/^((k?a|bi|bu|ge|o|ö)l)|dur|gör|san|v[aeu]r$/))+'r','0yor',(E?'y1c1':'1c1')+'ğkk'[--w]][t-1])+Z('0m|0z|s0n|s0n0z||l1r'.split`|`[w+w+p],t-2||(l='o')))

Unofofled y comentado

// Parameters:
//   - 'v' = verb
//   - 'p' = plural flag
//   - 'w' = person
//   - 't' = tense
(v, p, w, t) => (
  // R() - Helper function to execute a regular expression on the stem.
  R = g => g.exec(s),

  // T() - Helper function to replace the last character of the stem with 'r'.
  T = r => s = s.slice(0, -1) + r,

  // Z() - Function that applies vowel harmony to the string 's', assuming
  //       '0' = 'i' and '1' = 'e' and using the last encountered vowel 'l'.
  Z = s => s.replace(
    /\d/g,
    c => l = [
      'ıuiü' [(n = 'aıoueiöü'.search(l)) >> 1],
      'ae' [n >> 2]
    ][c]
  ),

  // Computes:
  //   - 's' = stem
  //   - 'k' = number of vowels in stem
  //   - 'l' = last vowel in stem
  //   - 'L' = penultimate vowel in stem
  (s = v.slice(k = l = 0, -3)).replace(/[aıoueiöü]/g, c => (L = l, l = c, k++)),

  // Applies ending 't' => 'd' for irregular verbs and those ending in -et(mek).
  (R(/^(gi|ta|di|gü)t$/) || (R(/et$/) && (k = 1))) && T `d`,

  // Computes 'E' = truthy value if the stem ends in a vowel.
  // If 'E' is truthy and the tense is the continuing present, drops this vowel.
  ((E = R(/[aıoueiöü]$/)) && t == 2 ? (l = L, T ``) : s) +

  // Appends sign of tense with vowel harmony.
  Z([
    // t = 1: simple present -> either '-er', '-ir' or '-r'
    (E ? '' : k < 2 & !R(/^((k?a|bi|bu|ge|o|ö)l)|dur|gör|san|v[aeu]r$/) + 'r',

    // t = 2: continuing present -> always '-iyor'
    '0yor',

    // t = 3: future -> either '-yecek', '-ecek', '-yeceğ' or '-eceğ'
    (E ? 'y1c1' : '1c1') + 'ğkk' [--w]
  ][t - 1]) +

  // Appends personal suffix with vowel harmony,
  // forcing last vowel to 'o' for continuing present.
  Z(
    '0m|0z|s0n|s0n0z||l1r'.split `|` [w + w + p],
    t - 2 || (l = 'o')
  )
)

Casos de prueba

let f =
(v,p,w,t)=>(R=g=>g.exec(s),T=r=>s=s.slice(0,-1)+r,Z=s=>s.replace(/\d/g,c=>l=['ıuiü'[(n='aıoueiöü'.search(l))>>1],'ae'[n>>2]][c]),(s=v.slice(k=l=0,-3)).replace(/[aıoueiöü]/g,c=>(L=l,l=c,k++)),(R(/^(gi|ta|di|gü)t$/)||(R(/et$/)&&(k=1)))&&T`d`,((E=R(/[aıoueiöü]$/))&&t==2?(l=L,T``):s)+Z([(E?'':k<2&!R(/^((k?a|bi|bu|ge|o|ö)l)|dur|gör|san|v[aeu]r$/))+'r','0yor',(E?'y1c1':'1c1')+'ğkk'[--w]][t-1])+Z('0m|0z|s0n|s0n0z||l1r'.split`|`[w+w+p],t-2||(l='o')))

console.log(f("gütmek", false, 1, 2));    // -> güdüyorum
console.log(f("almak", true, 3, 3));      // -> alacaklar
console.log(f("boğmak", true, 2, 1));     // -> boğarsınız
console.log(f("ölmek", false, 3, 1));     // -> ölür
console.log(f("boyamak", true, 1, 2));    // -> boyuyoruz
console.log(f("affetmek", false, 2, 1));  // -> affedersin
console.log(f("söylemek", true, 3, 1));   // -> söylerler
console.log(f("söylemek", false, 3, 2));  // -> söylüyor
console.log(f("söylemek", false, 1, 3));  // -> söyleyeceğim

Arnauld
fuente
¿Esto explica la dmutación en todos los verbos que terminan en -etmek ? No conozco JavaScript, pero por lo que puedo deducir, parece que se ha agrupado con los demás.
EMBLEMA
@EMBLEM: esto debe solucionarse.
Arnauld
4

sed, 583 bytes

sed -E 's/^((bul|dur|k?al|ol|san|v[au]r)ma|(bil|gel|gör|öl|ver)me)k( . .) 1/\2\3Ir\4/;s/etmek( . .) 1/edEr\1/;s/etmek /ed /;s/^((ta)tma|([dg]i|gü)tme)k /\2\3d /;s/m[ae]k / /;s/([aıoueiöüEI])/V\1/g;s/(V.)( . .) 1/\1r\2/;s/(V.+V.+)( . .) 1/\1VIr\2/;s/( . .) 1/VEr\1/;s/(V.)?( . .) 2/VIyVor\2/;s/(V.)( . . 3)/\1y\2/;s/( . .) 3/VEcVEk\1/;s/k( . 1)/ğ\1/;s/ 0 1/VIm/;s/ 1 1/VIz/;s/ 0 2/sVIn/;s/ 1 2/sVInVIz/;s/ 0 3//;s/ 1 3/lVEr/;:l
s/([ıa][^V]*V)I/\1ı/;s/([ie][^V]*V)I/\1i/;s/([uo][^V]*V)I/\1u/;s/([üö][^V]*V)I/\1ü/;s/([aıou][^V]*V)E/\1a/;s/(V[^aEI][^V]*V)E/\1e/;t l
s/V//g'

Al igual que mi respuesta a la pregunta del hexámetro Dactylic estrechamente relacionado , esto realmente solo está traduciendo las reglas como se dan en expresiones regulares.

Uso:

Toma entrada en el formulario:

word [01] [123] [123]

Entonces los casos de prueba son:

printf 'gütmek 0 1 2
almak 1 3 3
boğmak 1 2 1
ölmek 0 3 1
boyamak 1 1 2
affetmek 0 2 1
söylemek 1 3 1
söylemek 0 3 2
söylemek 0 1 3' | sed -E '<...>';

Descompostura:

sed -E "
# special cases for simple present tense
 s/^((bul|dur|k?al|ol|san|v[au]r)ma|(bil|gel|gör|öl|ver)me)k( . .) 1/\2\3Ir\4/;

# stemming
# always uses -er rule if simple present
 s/etmek( . .) 1/edEr\1/;
 s/etmek /ed /;
 s/^((ta)tma|([dg]i|gü)tme)k /\2\3d /;
 s/m[ae]k / /;

# mark vowels for easier expressions later
 s/([aıoueiöüEI])/V\1/g;

# simple present
 s/(V.)( . .) 1/\1r\2/;
 s/(V.+V.+)( . .) 1/\1VIr\2/;
 s/( . .) 1/VEr\1/;

# continuing present
 s/(V.)?( . .) 2/VIyVor\2/;

# future
 s/(V.)( . . 3)/\1y\2/;
 s/( . .) 3/VEcVEk\1/;

# personal suffix
 s/k( . 1)/ğ\1/;
 s/ 0 1/VIm/;
 s/ 1 1/VIz/;
 s/ 0 2/sVIn/;
 s/ 1 2/sVInVIz/;
 s/ 0 3//;
 s/ 1 3/lVEr/;

# vowel harmony
 :l
 s/([ıa][^V]*V)I/\1ı/;
 s/([ie][^V]*V)I/\1i/;
 s/([uo][^V]*V)I/\1u/;
 s/([üö][^V]*V)I/\1ü/;

 s/([aıou][^V]*V)E/\1a/;
 s/(V[^aEI][^V]*V)E/\1e/;
# keep looping until all vowels are known
 t l

# unmark vowels
 s/V//g
"

Resultados para casos de prueba:

güdüyorum
alacaklar
boğarsınız
ölür
boyuyoruz
affedersin
söylerler
söylüyor
söyleyeceğim
Dave
fuente
Tienes razón sobre affedersin. Cambié los pronombres varias veces mientras escribía eso
EMBLEMA
Tomar nota del caso 2; debería ser alacak lar , no ler.
EMBLEMA
@EMBLEM arreglado; Sin embargo, me costó 2 bytes más (pero ¿qué son 2 bytes en 600?)
Dave
Puede eliminarlo sed -E '', ya que especificó sed como el idioma y no como bash, así que considere el script como código fuente de sed. Luego puede ejecutarlo como: printf ...|sed -Ef filenameagregando 1 byte más para la bandera E, ahorrando 8 bytes al final. Por cierto, nunca supe hasta hoy que -E es equivalente a -r!
seshoumara