Ruby, 8618 benar (91,1%), 53 byte, 8618 - 10 * 53 = 8088 skor
->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}
Ini adalah fungsi Ruby anonim yang menggunakan regex untuk menghitung suku kata.
Fungsi ini menambahkan suku kata untuk setiap instance dari:
- Serangkaian non-
e
vokal, diikuti oleh nol e
s lebih
- Suatu
e
yang bukan bagian dari trailing ed
atau ely
, dengan pengecualian trailing ted
atau ded
s
- A tertinggal
le
Analisis
Ide dasarnya adalah untuk menghitung jumlah huruf vokal, tetapi ini dengan sendirinya tidak terlalu akurat ( [aeiouy]+
mendapatkan 74% benar). Alasan utama untuk ini adalah karena diame
, yang memodifikasi suara vokal sebelumnya sementara tidak diucapkan sendiri. Misalnya, kata tersebut slate
memiliki dua vokal tetapi hanya satu suku kata.
Untuk mengatasinya, kami mengambil e
bagian pertama dari regex dan memperlakukannya secara terpisah. Mendeteksi silent e
s sulit, tetapi saya menemukan dua kasus di mana mereka sering terjadi:
- Sebagai bagian dari Trailing
ed
(kecuali itu adalah ted
atau ded
seperti settled
atau saddled
),
- Sebagai bagian dari trailing
evy
(mis. lovely
)
Kasus-kasus ini secara khusus dikecualikan dalam apa yang seharusnya e.
.
Alasan untuk .
di e(?!d$|ly).
adalah untuk mengkonsumsi char berikutnya jika ada vokal ganda (misalnya ea
atau ee
), dan e
pada akhir kata tidak dihitung. Namun Trailing le
yang biasanya diucapkan, sehingga ditambahkan kembali.
Akhirnya, vokal berjalan dihitung sebagai satu suku kata. Meskipun hal ini tidak selalu terjadi (mis. curious
), Seringkali sulit untuk mengetahui apakah ada banyak suku kata. Ambil ia
dari celestial
dan spatial
, sebagai contoh.
Program uji
Saya tidak begitu mengenal Ruby, jadi saya tidak yakin seberapa bagus golfnya. Saya berhasil mengikis bersama program uji dengan berkonsultasi banyak SO meskipun:
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}"