Ruby, 8618 correct (91,1%), 53 octets, 8618 - 10 * 53 = score 8088
->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}
Il s'agit d'une fonction Ruby anonyme qui utilise des expressions rationnelles pour compter les syllabes.
La fonction ajoute une syllabe pour chaque instance de:
- Une série de non-
e
voyelles, suivie de zéro de plus e
s
- Un
e
qui ne fait pas partie d'un suivi ed
ou ely
, à l'exception du suivi ted
ou ded
s
- Une fuite
le
Une analyse
L'idée de base est de compter les séries de voyelles, mais ce n'est pas très précis en soi (il [aeiouy]+
est correct à 74%). La raison principale en est le silencee
, qui modifie le son de voyelle précédent sans être prononcé lui-même. Par exemple, le mot slate
a deux voyelles mais une seule syllabe.
Pour y faire face, nous retirons e
la première partie de l'expression rationnelle et la traitons séparément. Détecter les e
s silencieux est difficile, mais j'ai trouvé deux cas où ils se produisent souvent:
- Dans le cadre d'un suivi
ed
(sauf s'il s'agit d'un ted
ou ded
comme settled
ou saddled
),
- Dans le cadre d'une fuite
evy
(par exemple lovely
)
Ces cas sont spécifiquement exclus de ce qui serait autrement e.
.
La raison de l' .
entrée e(?!d$|ly).
est de consommer le caractère suivant s'il y a une voyelle double (par exemple ea
ou ee
), et de sorte qu'à e
la fin du mot ne soit pas compté. Cependant, une fuite le
est généralement prononcée, de sorte qu'elle est ajoutée à nouveau.
Enfin, les voyelles sont comptées comme une syllabe. Bien que cela ne soit pas toujours le cas (par exemple curious
), il est souvent difficile de déterminer s'il existe plusieurs syllabes. Prenez le ia
de celestial
et spatial
, à titre d'exemple.
Programme de test
Je ne connais pas vraiment Ruby, donc je ne sais pas à quel point il peut être joué au golf. J'ai réussi à rassembler un programme de test en consultant beaucoup de SO cependant:
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}"