Syllabify palabras en inglés - tipo de

11

Tiene la tarea de escribir un programa que sillabice palabras en una cadena de texto, separándolas con un guión. Eso sería mucho trabajo, por lo que desea omitir algunas partes, principalmente porque no desea tener una tabla de las pronunciaciones necesarias para un algoritmo perfecto. También debes hacerlo lo más breve posible (y, por lo tanto, ilegible e imposible de mantener) como venganza por recibir esta tarea.

Tienes dos opciones:

  • Escriba un programa que tome la cadena de STDIN y envíe el resultado a STDOUT.
  • Escriba una función que tome la cadena como un solo parámetro y devuelva el resultado.

Especificación

  • En este caso, cadena significa cualquier construcción similar a una cadena en el idioma de su elección (matrices de bytes, matrices de caracteres, cadenas ...).
  • Las vocales son a, e, i, o, u
  • La cadena dada tiene 1 <= n <= 10palabras, donde cada una tiene una longitud entre 1 - 30caracteres, inclusive. Su salida debe ser esas palabras con guiones.
  • Todas las letras son minúsculas y las palabras siempre están separadas por espacios. Por lo tanto, la entrada consta de caracteres[a-z ]
  • Aplicar reglas en orden de importancia.
  • Cuando se divide una palabra, comience nuevamente con la mitad derecha de la palabra.

Reglas para la silábificación , en orden de importancia

Dos mismas vocales consecutivas contar como uno (es decir. feetSólo hay una vocal, pero beaty findingtiene dos). Cada sílaba tiene exactamente una vocal, por lo tanto, hay una sílaba para cada vocal.

  1. Si toda la palabra tiene solo cuatro letras, devuélvala sin cambios. (omita esto por el resto de la palabra)
  2. Si la palabra tiene solo una vocal, devuélvala sin cambios.
  3. Si la palabra tiene dos vocales consecutivas, divídalas entre ellas (es decir, diaspora-> di-as-po-ra)
  4. Cuando dos o más consonantes se interponen entre dos vocales (iguales o diferentes), divida después de la primera consonante (es decir sis-ter), a menos que la parte consonante lo sea ck, en cuyo caso divida la palabra después de ella. (es decir. nickel-> nick-el)
  5. Cuando a yviene entre dos vocales, divide la palabra después (ej. paying-> pay-ing).
  6. Cuando una consonante se interpone entre dos vocales (iguales o diferentes), divida antes de la consonante (es decir dra-gon) .
  7. Devuelva la palabra sin cambios si no se puede hacer una división.

Elegí estas reglas porque se pueden aplicar de forma recursiva sin problemas y no requieren tablas de pronunciación. Por lo tanto, no son precisos y, por ejemplo, la regla 5 a menudo no es correcta. En general, sin embargo, lo es.

Ejemplo

In:  hello world
Out: hel-lo world

In:  have a nice day
Out: have a nice day

In:  pour some nickel and xenon there
Out: pour some nick-el and xe-non the-re
seequ
fuente
¿Estás seguro x-e-non? ¿Referencia para la regla # 4?
John Dvorak
@ JanDvorak "Cuando una palabra se divide, comience nuevamente con la mitad derecha de la palabra", seguido de la regla # 6.
seequ
Quiero decir, ¿no debería la regla # 4 dividirse solo entre sílabas?
John Dvorak
1
La regla # 1 trata con palabras de cuatro letras. ¿Qué pasa con las palabras con menos de cuatro letras? Por ejemplolua
Trauma digital
1
@DigitalTrauma Se proscriben normalmente, pero rara vez tienen dos sílabas.
seequ

Respuestas:

6

Ruby, 144 bytes

Si vamos por lo imposible, ¿qué tal una expresión regular gigante?

puts gets.split.map {|w| w.scan(/(^.{4}$|[^aeiou]*([aeiou])\2?((?=[^aeiouy]?[aeiou])|ck|[^aeiou]((?=.*[aeiou])|.*$)|$))/).map(&:first)*'-'}*' '

alguna salida:

echo "hello world" | ruby syllable.rb
hel-lo world

echo "have a nice day" | ruby syllable.rb
have a nice day

echo "pour some nickel and xenon in there" | ruby syllable.rb
pour some nick-el and xe-non in the-re

echo "diaspora dragon paying sister hemlock happy quicksilver" | ruby syllable.rb
di-as-po-ra dra-gon pay-ing sis-ter hem-lock happy qu-ick-sil-ver
YenTheFirst
fuente
8

Lua, 292

Puede que Lua no haya sido el mejor idioma para hacerlo, pero funciona. Fluye más o menos como la pregunta que se hace. Las reglas están principalmente en orden con algunas optimizaciones: se omite el n. ° 2 (no es necesario a menos que haya una palabra vocal con "ck" al principio), y las reglas ck e y se pasan antes que el resto de # 4 y # 6, que se combinan. Dado que algunas vocales en la palabra deben capturarse dos veces (después de un guión y antes de otro), esa búsqueda se realiza dos veces.

i=io.read()v="([aeiou])"for s in i:gfind("%l+ ?")do
if s:len()~=4 then
s=s:gsub(v..v,function(x,y)if x==y then return x..y;end;return x.."-"..y;end)s=s:gsub("ck"..v,"ck-%1")s=s:gsub(v.."y"..v,"%1y-%2")for b=1,2 do
s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")end
end
io.write(s)end

Sin golf

function checkEquals(x,y)
    if x==y then 
        return x..y
    end
    return x.."-"..y
end
i=io.read()
v="([aeiou])"
for s in i:gfind("%l+ ?") do
    if s:len()~=4 then
        s=s:gsub(v..v,checkEquals)
        s=s:gsub("ck"..v,"ck-%1")
        s=s:gsub(v.."y"..v,"%1y-%2")
        for b=1,2 do
            s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")
        end
    end
    io.write(s)
end

Pruébelo aquí: http://ideone.com/g57TzA

Nexo
fuente
No tengo rubí, pero parece estar bien.
seequ
4

Bash + coreultils, 173 bytes

Creo que tengo todos los últimos cambios de reglas:

v=aeiou
r="[$v])/\1-\2/g"
s=s/\([$v]
e="$s[^$v-])([^$v-]+$r
"
tr \  \\n|sed -r "/^([a-z]{4}|[^$v]*[$v][^$v]*)$/bx
$s)($r
${s}ck)($r
$e$e${s}y)($r
$s)([^$v-]$r
:x"|tr \\n \ 

Tenga en cuenta que el último carácter de la última línea es un (espacio).

Creo que esto satisface suficientemente "ilegible e imposible de mantener" ;-)

Toma información de STDIN.

Principalmente sustitución de expresiones regulares. La primera línea de la sedexpresión coincide con las reglas 1 y 2, luego simplemente salta a la :xetiqueta al final de la expresión.

Los trs al principio y al final de la tubería hacen que las palabras estén separadas por una nueva línea, por lo que es más fácil sedtratarlas. Esperaba hacerlo y todos sedresponden, pero de esta manera es más simple y más fácil.

Ejemplo:

$ ./sylabify.sh <<< "diaspora nickel sister dragon hello world have a nice day pour some nickel and xenon there paying tricks quicksilver"
di-as-po-ra nick-el sis-ter dra-gon hel-lo world have a nice day pour some nick-el and xe-non the-re pay-ing tricks qu-ic-ksil-ver $ 
Trauma digital
fuente
Argh, sigo olvidando que la regla # 3 cambió. Está bien.
seequ