Ruby, 8618 đúng (91,1%), 53 byte, 8618 - 10 * 53 = 8088 điểm
->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}
Đây là một hàm Ruby ẩn danh sử dụng biểu thức chính quy để đếm các âm tiết.
Hàm thêm một âm tiết cho mọi trường hợp:
- Một loạt các
e
nguyên âm, theo sau là 0 của nhiều e
s
- Một
e
cái không phải là một phần của dấu ed
hoặc ely
, ngoại trừ dấu ted
hoặc ded
s
- Một dấu
le
Phân tích
Ý tưởng cơ bản là đếm số lần chạy nguyên âm, nhưng điều này tự nó không chính xác lắm ( [aeiouy]+
được 74% chính xác). Lý do chính cho điều này là do sự im lặnge
, điều chỉnh âm nguyên âm trước đó trong khi không được phát âm. Ví dụ, từ slate
này có hai nguyên âm nhưng chỉ có một âm tiết.
Để giải quyết vấn đề này, chúng tôi e
loại bỏ phần đầu tiên của regex và xử lý nó một cách riêng biệt. Phát hiện sự im lặng e
là khó, nhưng tôi đã tìm thấy hai trường hợp chúng xảy ra thường xuyên:
- Là một phần của dấu vết
ed
(trừ khi nó là ted
hoặc ded
thích settled
hoặc saddled
),
- Là một phần của dấu vết
evy
(ví dụ lovely
)
Những trường hợp này được đặc biệt loại trừ trong những gì sẽ được e.
.
Lý do cho việc .
nhập e(?!d$|ly).
là để tiêu thụ char tiếp theo nếu có nguyên âm đôi (ví dụ ea
hoặc ee
), và do đó e
ở cuối từ không được tính. Tuy nhiên một dấu le
là thường phát âm, do đó được bổ sung trở lại trong.
Cuối cùng, các nguyên âm chạy được tính là một âm tiết. Mặc dù điều này có thể không phải luôn luôn như vậy (ví dụ curious
), nhưng thường rất khó để biết liệu có nhiều âm tiết hay không. Lấy ia
của celestial
và spatial
, như một ví dụ.
Chương trình kiểm tra
Tôi thực sự không biết Ruby nên tôi không chắc nó có thể chơi golf tốt như thế nào. Tôi đã cố gắng để cùng nhau tạo ra một chương trình thử nghiệm bằng cách tham khảo rất nhiều 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}"