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-
e
Vokalen, gefolgt von null oder mehr e
s
- Ein
e
was ist nicht Teil eines Trailings ed
oder ist ely
, mit Ausnahme von Trailing ted
oder ded
s
- 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 slate
zwei 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 e
s 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 ded
wie settled
oder 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. ea
oder ee
), und damit e
am 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 ia
voncelestial
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}"