Ruby, 8618 correto (91,1%), 53 bytes, 8618 - 10 * 53 = pontuação do 8088
->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}
Esta é uma função Ruby anônima que usa expressões regulares para contar sílabas.
A função adiciona uma sílaba para cada instância de:
- Uma sequência de não
e
vogais, seguida por zero de mais e
s
- Um
e
que não faz parte de um trailing ed
ou ely
, com exceção de trailing ted
ou ded
s
- Um rastro
le
Análise
A idéia básica é contar as execuções de vogais, mas isso por si só não é muito preciso ( [aeiouy]+
fica 74% correto). A principal razão para isso é o silêncioe
, que modifica o som da vogal anterior sem ser pronunciado. Por exemplo, a palavra slate
tem duas vogais, mas apenas uma sílaba.
Para lidar com isso, retiramos e
a primeira parte do regex e o tratamos separadamente. Detectar e
s silenciosos é difícil, mas encontrei dois casos em que ocorrem com frequência:
- Como parte de uma fuga
ed
(a menos que seja uma ted
ou ded
semelhantes settled
ou saddled
),
- Como parte de uma trilha
evy
(por exemplo lovely
)
Esses casos são especificamente excluídos do que seria de outra forma e.
.
A razão para a .
em e(?!d$|ly).
é consumir o próximo carvão animal se existe uma dupla vogal (por exemplo, ea
ou ee
), e de modo que e
no fim da palavra não são contados. No entanto, um final le
é geralmente pronunciado, de modo que é adicionado novamente.
Finalmente, as execuções de vogais são contadas como uma sílaba. Embora nem sempre seja esse o caso (por exemplo curious
), geralmente é difícil descobrir se há várias sílabas. Pegue o ia
de celestial
e spatial
, como um exemplo.
Programa de teste
Eu realmente não conheço Ruby, então não tenho certeza de quão bem ele pode ser jogado no golfe. Consegui reunir um programa de teste consultando muito SO:
cases = 0
correct = 0
s = "->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}"
f = eval s
for i in 1 ... 8
filepath = i.to_s + "-syllable-words.txt"
file = File.open(filepath)
while (line = file.gets)
word = line.strip
cases += 1
if f.call(word) == i
correct += 1
end
end
end
p "Correct: #{correct}/#{cases}, Length: #{s.length}, Score: #{correct - s.length*10}"