Silabificar palavras em inglês - tipo de

11

Você é encarregado de escrever um programa que silabifique palavras em uma sequência de texto, separando-as com um hífen. Isso daria muito trabalho, então você quer pular algumas partes, principalmente porque não deseja ter uma tabela com as pronúncias necessárias para um algoritmo perfeito. Você também deseja torná-lo o mais curto possível (e, portanto, ilegível e impossível de manter), como uma vingança por receber essa tarefa.

Você tem duas opções:

  • Escreva um programa que retire a string de STDIN e envie o resultado para STDOUT.
  • Escreva uma função que use a string como um único parâmetro e retorne o resultado.

Especificação

  • Nesse caso, string significa qualquer construção semelhante a string no idioma de sua escolha (matrizes de bytes, matrizes de caracteres, strings ...).
  • As vogais são a, e, i, o, u
  • A cadeia de caracteres fornecida possui 1 <= n <= 10palavras, onde cada uma possui um comprimento entre 1 - 30caracteres, inclusive. Sua saída deve ser essas palavras hifenizadas.
  • Todas as letras são minúsculas e as palavras são sempre separadas por espaços. Assim, a entrada consiste em caracteres[a-z ]
  • Aplique regras em ordem de importância.
  • Quando uma palavra é dividida, comece novamente com a metade direita da palavra.

Regras para silabificação , em ordem de importância

Dois mesmas vogais consecutivos contar como um (isto é. feetTem apenas uma vogal, mas beate findingtem dois). Cada sílaba tem exatamente uma vogal, portanto, há uma sílaba para cada vogal.

  1. Se a palavra inteira tiver apenas quatro letras, retorne-a inalterada. (pule isso pelo resto da palavra)
  2. Se a palavra tiver apenas uma vogal, retorne a palavra inalterada.
  3. Se a palavra tiver duas vogais consecutivas, divida entre elas (por exemplo, diaspora-> di-as-po-ra)
  4. Quando duas ou mais consoantes estiverem entre duas vogais (iguais ou diferentes), divida após a primeira consoante (ie. sis-ter), A menos que a parte da consoante seja ck, nesse caso, divida a palavra após ela. (ie. nickel-> nick-el)
  5. Quando a yaparecer entre duas vogais, divida a palavra depois dela (por exemplo, paying-> pay-ing).
  6. Quando uma consoante estiver entre duas vogais (iguais ou diferentes), divida antes da consoante (ou seja dra-gon) .
  7. Retorne a palavra inalterada se nenhuma divisão puder ser feita.

Eu escolhi essas regras, porque elas podem ser aplicadas recursivamente sem problemas e não requerem tabelas de pronúncia. Portanto, eles não são precisos e, por exemplo, a regra 5 geralmente não está correta. Em geral, porém, é.

Exemplo

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
fonte
Você tem certeza x-e-non? Referência para a regra 4?
John Dvorak
@JanDvorak "Quando uma palavra é dividida, comece novamente com a metade direita da palavra.", Seguida pela regra # 6.
see
Quero dizer, a regra nº 4 não deve ser dividida apenas entre sílabas?
22414 John Dvorak
1
A regra nº 1 trata de palavras com quatro letras. E as palavras com menos de quatro letras? por exemplolua
Digital Trauma
1
@DigitalTrauma Eles são processados ​​normalmente, mas raramente têm duas sílabas.
seequ

Respostas:

6

Ruby, 144 bytes

Se estamos indo para o impossível, que tal um único regex gigante?

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

alguma saída:

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

Lua, 292

Lua pode não ter sido a melhor linguagem para fazer isso, mas funciona. É praticamente como a pergunta. As regras estão principalmente em ordem com algumas otimizações: o número 2 é ignorado (não é necessário, a menos que exista uma palavra com uma vogal com "ck" no início), e as regras ck e y são implementadas antes do resto de # 4 e # 6, que são combinados. Como algumas vogais da palavra precisam ser capturadas duas vezes (após um hífen e antes de outro), essa pesquisa é realizada duas vezes.

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

Ungolfed

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

Teste aqui: http://ideone.com/g57TzA

Nexo
fonte
Eu não tenho rubi, mas parece bom mesmo.
see
4

Bash + coreultils, 173 bytes

Eu acho que tenho todas as alterações mais recentes das regras:

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 \ 

Observe que o último caractere da última linha é um (espaço).

Eu acho que isso satisfaz suficientemente "ilegível e insustentável" ;-)

Recebe entrada de STDIN.

Substituição de regex principalmente direta. A primeira linha da sedexpressão corresponde às regras 1 e 2 e simplesmente salta para o :xrótulo no final da expressão.

Os trs no início e no final do pipeline tornam as palavras separadas por nova linha, para que sejam mais fáceis de sedlidar. Eu esperava fazer e sedresponder todas , mas dessa maneira é mais simples e fácil.

Exemplo:

$ ./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
fonte
Argh, continuo esquecendo que a regra nº 3 mudou. Está bem.
Veja