Ruby, 8618 korrekt (91,1%), 53 Byte, 8618 - 10 * 53 = 8088 Punkte
->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}
Dies ist eine anonyme Ruby-Funktion, die reguläre Ausdrücke verwendet, um Silben zu zählen.
Die Funktion fügt eine Silbe für jede Instanz von:
- Eine Folge von Nicht-
eVokalen, gefolgt von null oder mehr es
- Ein
ewas ist nicht Teil eines Trailings edoder ist ely, mit Ausnahme von Trailing tedoder deds
- Ein schleppendes
le
Analyse
Die Grundidee ist, Vokalläufe zu zählen, aber das ist an sich nicht sehr genau ([aeiouy]+ 74% richtig). Der Hauptgrund dafür liegt in der Stillee , die den vorherigen Vokalton verändert, ohne selbst ausgesprochen zu werden. Zum Beispiel hat das Wort slatezwei Vokale, aber nur eine Silbe.
Um damit umzugehen, nehmen wir e den ersten Teil des regulären Ausdrucks heraus und behandeln ihn separat. Das Erkennen stiller es ist schwierig, aber ich habe zwei Fälle gefunden, in denen sie häufig auftreten:
- Als Teil eines Trailings
ed(es sei denn, es ist einted oder dedwie settledoder saddled),
- Im Rahmen eines Trailings
evy (zB lovely)
Diese Fälle sind im Übrigen ausdrücklich ausgeschlossen e..
Der Grund für das .In e(?!d$|ly).ist, das nächste Zeichen zu verbrauchen, wenn es einen Doppelvokal gibt (z. B. eaoder ee), und damit eam Ende des Wortes nicht gezählt werden. Allerdings ein Nachlaufle ist Regel ausgesprochen, so dass wieder in hinzugefügt wird.
Schließlich werden Vokalläufe als eine Silbe gezählt. Dies ist möglicherweise nicht immer der Fall (z. B. curious), es ist jedoch oft schwierig herauszufinden, ob mehrere Silben vorhanden sind. Nehmen Sie das iavoncelestial und spatial, als Beispiel.
Testprogramm
Ich kenne Ruby nicht wirklich, also bin ich mir nicht sicher, wie gut es golfen kann. Es ist mir gelungen, ein Testprogramm zusammenzustellen, indem ich viel SO konsultiert habe:
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}"