단어로 음절을 세는 방법


22

입력 : 영어 단어 하나가 포함 된 문자열이 전달됩니다. 모든 문자는 소문자이며 문자열에 알파벳이 아닌 문자가 없습니다.

출력 : 단어에 몇 개의 음절이 있다고 생각하는지 나타내는 1에서 7까지의 정수를 반환합니다.

스코어링 : 이 저장소 에있는 모든 단어에 대해 프로그램이 실행됩니다 . 당신이 얻을 경우 N단어를 수정하고 프로그램이 M큰 바이트, 당신의 점수입니다 N-(M*10). 가장 큰 점수가 이깁니다.

내 음절 수를 생성하려면, 내가 사용 내 단어 목록으로와 음절을 계산.


3 음절 단어에는 "inn"과 "ruby"가 있습니다. 2 음절 단어에는 "irs", "ore", "roy", "yer"가 포함됩니다. 그 외에는 목록이 충분히 정확 해 보입니다.
justhalf

@justhalf 감사합니다. 목록을 작성하는 것이 가장 어려운 과제였습니다.
Nathan Merrill


3
이 도전은 어리석은 영어가 얼마나 될 수 있는지 깨닫게 해줍니다. 가라 resume... 예를 들면
SP3000

답변:


12

루비, 8618 정확한 (91.1 %), 53 바이트, 8618-10 * 53 = 8088 점수

->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}

이것은 정규 표현식을 사용하여 음절을 세는 익명의 루비 함수입니다.

이 함수는 다음의 모든 인스턴스에 음절을 추가합니다.

  • 비의 실행 e이상 0으로 다음 모음, e
  • e되는 하지 말미의 일부 ed또는 ely후단을 제외 ted또는 dedS
  • 후행 le

분석

기본 아이디어는 모음을 세는 것이지만 그 자체로는 정확하지 않습니다 ( [aeiouy]+74 % 정확함). 이것의 주된 이유는 조용한e 소리로 인해 이전 모음 사운드를 수정하지 않고 자체적으로 발음하기 때문입니다. 예를 들어, 단어 slate에는 모음이 두 개 있지만 음절이 하나만 있습니다.

이를 처리하기 위해 e정규식의 첫 부분을 꺼내어 별도로 처리합니다. 침묵을 감지하는 e것은 어렵지만 자주 발생하는 두 가지 경우를 발견했습니다.

  • 후행의 일부로 ed( ted또는 dedsettled거나 같지 않은 경우 saddled)
  • 말미의 일부로서 evy(예 lovely)

이러한 경우는 다른 방법으로 제외됩니다 e..

.in 의 이유 e(?!d$|ly).는 이중 모음 (예 : ea또는 ee) 이있는 경우 다음 문자를 사용하기 때문에 e단어의 끝에서 계산되지 않습니다. 그러나 후행 le 일반적으로 발음되므로 다시 추가됩니다.

마지막으로 모음 실행은 한 음절로 계산됩니다. 항상 그런 것은 아니지만 (예 curious:) 여러 음절이 있는지 확인하기가 어려운 경우가 많습니다. 를 타고 iacelestialspatial예를 들어,.

테스트 프로그램

나는 루비를 잘 몰라서 골프를 얼마나 잘 할 수 있는지 잘 모르겠습니다. 나는 많은 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}"

아, 당신은 표준을 너무 높게 만들었습니다. 파이썬에서는 코드 길이가 정확히 20 자 이상이므로 "Vowel 다음에 문자가 아닌 문자"를 구현 e하면 6638 (7158이 맞음)
justhalf

2
@justhalf 루비를 사용하는 이유는 기본적으로 유일한 이유입니다. : PI는 일반적으로 다른 모든 것에 파이썬을 사용합니다.
Sp3000

5

Python3, 7935-10 * 71 = 7225

나의 빠른 대답 : 연속 모음의 런 수를 세지 만 마지막 e는 먼저 제거하십시오.

lambda w:len(''.join(" x"[c in"aeiouy"]for c in w.rstrip('e')).split())

e를 벗기고 나면 모음이 바뀌고 x다른 모든 문자는 공백으로 바뀝니다 . 결과는 다시 문자열로 결합 된 다음 공백으로 분할됩니다. 편리하게 시작과 끝의 공백은 무시됩니다 (예 : " x xx ".split()제공 ["x","xx"]). 결과 목록의 길이는 모음 그룹의 수입니다.

아래의 원래 83 바이트 답변은 끝에 하나의 e 만 제거했기 때문에 더 정확했습니다. 새로운 것은 따라서 다음과 같은 단어에 문제가있다 bee. 그러나 단축 된 코드는 그 효과보다 큽니다.

lambda w:len(''.join(" x"[c in"aeiouy"]for c in(w[:-1]if'e'==w[-1]else w)).split())

테스트 프로그램 :

syll = lambda w:len(''.join(c if c in"aeiouy"else' 'for c in w.rstrip('e')).split())

overallCorrect = overallTotal = 0
for i in range(1, 7):
    with open("%s-syllable-words.txt" % i) as f:
        words = f.read().split()
    correct = sum(syll(word) == i for word in words)
    total = len(words)
    print("%s: %s correct out of %s (%.2f%%)" % (i, correct, total, 100*correct/total))
    overallCorrect += correct
    overallTotal += total

print()
print("%s correct out of %s (%.2f%%)" % (overallCorrect, overallTotal, 100*overallCorrect/overallTotal))

분명히 이것은 너무 지저분 해져 Sp3000의 Ruby 답변을 이길만큼 빠르지 않았습니다. ; ^)


->s{s.scan(/([aiouy]|e(?!$))+/).size}점수는 7583 점입니다. 84 %는 아주 간단한 것에 대해 매우 인상적입니다.
Sp3000

1

펄, 8145-3 * 30 = 7845

최근 커밋 이전의 목록을 사용합니다.

#!perl -lp
$_=s/(?!e[ds]?$)[aeiouy]+//g

파일이 최근에 업데이트되었습니다. 나는 한 음절 파일에 이름을 붙인 단어를 보지 못했습니다.
Sp3000

@ Sp3000, 위 어드. 그들은 내가 본 것에 따라 7 시간 전에 업데이트되었으며, 그 링크에는 여전히 github.com/nathanmerrill/wordsbysyllables/blob/master/…
nutki

@NathanMerrill이 7 시간 전에 업데이트를 엉망인 것 같습니다 : history .
Sp3000

@ Sp3000, 감사합니다. 점수를 이전 버전으로 업데이트합니다. 이 목록에는 여전히 몇 가지 오류가 있지만 심각하지는 않습니다.
nutki

0

파이썬, 5370-10 * 19 = 5180

이 프로그램은 단순히 단어가 길수록 음절이 더 많다고 가정합니다.

lambda x:len(x)/6+1

내가 사용하는 테스터 프로그램은 다음과 같습니다.

correct = 0
y = lambda x:len(x)/6+1
for i in xrange(1,8):
    f = file(str(i)+"-syllable-words.txt")
    lines = f.read().split("\n")
    f.close()
    correct += len([1 for line in lines if y(line)==i])
print correct

프로그램이나 함수를 만들어야합니까? 당신은 프로그램이 아니며 실행할 때 아무것도 출력하지 않습니다.
justhalf

@justhalf 입력을 받아들이고 출력을 생성하는 것이 필요합니다 (출력이 STDIO가 아니더라도)
Nathan Merrill

Btw 7을 사용하여 5150을 얻지 못했지만 4391을 얻었습니다. 내 테스트에서는 len(x)/6대신 사용하는 것이 좋습니다 (5377-190 = 5187).
justhalf

@justhalf 업데이트를 통해 5343을 얻었지만 len (x) / 6을 사용하면 분명히 더 나쁜 점수를 얻습니다. 테스트 프로그램을 게시하겠습니다.
Nathan Merrill

readlines()결과에 개행을 포함시킵니다. 그래서 당신은 실제로 (len(x)+1)/7+1입니다. read().split('\n')대신 사용해야 합니다. 그래도 그 공식에 대해 5352를 얻었지만.
justhalf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.