가독성 지수 구축


13

플레시-킨케이드 가독성 알고리즘은 전체 대물, 또는 컴퓨터를 사용하여 쉽게 오토메이션이며, 어느 것도 단어 수 카운트와 음절의 측정에 의존한다. 예를 들어, 하이픈과 함께 "code-golf"는 한 단어 또는 두 단어로 계산됩니까? "백만"이라는 단어가 두세 음절입니까? 이 작업에서는 계산에 시간, 공간 및 가장 중요한 코드가 너무 많이 걸리므로 대략적인 계산이 필요합니다.

당신의 임무는 영어 독해 구절 (완전한 문장으로 가정 됨)을 취하는 모든 언어로 가능한 가장 작은 프로그램 (즉, 기능)을 구축하고, 8 점의 공차로 Flesch Reading Ease 지수를 계산하는 것입니다. 음절 계산 및 단어 계산의 변형). 다음과 같이 계산됩니다.

FRE = 206.835 - 1.015 * (words per sentence) - 84.6 * (syllables per word)

프로그램은 수동 참조를 사용하여 지수가 계산 된 아래 참조 구절과 일치해야합니다.

I would not, could not, in the rain.
Not in the dark, not on a train.
Not in a car, not in a tree.
I do not like them, Sam, you see.
Not in a house, not in a box.
Not with a mouse, not with a fox.
I will not eat them here or there.
I do not like them anywhere!

색인 : 111.38 (8 문장에서 62 단어로 64 음절)

It was a bright cold day in April, and the clocks were striking thirteen.
Winston Smith, his chin nuzzled into his breast in an effort to escape
the vile wind, slipped quickly through the glass doors of Victory Mansions,
though not quickly enough to prevent a swirl of gritty dust from entering
along with him.

색인 : 65.09 (2 문장으로 55 단어로 된 74 음절)

When in the Course of human events, it becomes necessary for one people to
dissolve the political bands which have connected them with another, and to
assume among the powers of the earth, the separate and equal station to
which the Laws of Nature and of Nature's God entitle them, a decent respect
to the opinions of mankind requires that they should declare the causes
which impel them to the separation.

색인 : 3.70 (1 문장에서 71 단어로 된 110 음절)

음절과 단어를 수동으로 세고 색인을 계산 한 다른 구절이 있으면이를 확인으로 표시 할 수 있습니다.


기능이 될 수 있습니까? 아니면 STDIN을 복용해야합니까?
Brigand

2
3 가지 예제 구절에 대한 음절 개수를 사용할 수 있습니까, 아니면 색인 만 있습니까? 당신이 그것을 가지고 있다면, 음절 수는 비교하기에 편리 할 것입니다.
Strigoides

기능 일 수 있습니다. 실제로는 기능이어야합니다.
Joe Z.

답변:


6

펄 120 바이트

#!perl -pa0
s@\w+|([.!?])@$s+=$#-,lc($&)=~s![aeiou]+\B|([aeiouy]$)!$y+=1-$#-/3!ger@ge}
{$_=206.835-1.015*@F/$s-84.6*$y/@F

샘플 I / O :

$ perl flesch-kincaid.pl < input1.dat
110.730040322581

$ perl flesch-kincaid.pl < input2.dat
65.6097727272728

$ perl flesch-kincaid.pl < input2.dat
1.71366197183096

음절 수는 단어의 끝에있는 고독 모음을 제외하고 각 모음 모음이 단일 음절이라고 가정하여 수행됩니다. 단 3 분의 2 만 계산됩니다. 상당히 정확한 것으로 보이는 휴리스틱.


3

K & R C - 188 196 199 229

사양을 변경하여 함수를 지정하면 카운트에서 많은 c 오버 헤드를 얻을 수 있습니다. 또한 Strigoides의 음절 계산 해킹을 사용하도록 변경했습니다.

슬프게도 기반으로 모음 탐지를 수행하는 짧은 방법을 찾은 후 stdchr지루할 필요가 없도록 사용했던 비트 트위들 링 혐오 중 몇 가지를 더 짜낼 인센티브가있었습니다.

d,a,v,s,t,w;float R(char*c){for(;*c;++c){s+=*c=='.';if(isalpha(*c)){
w+=!a++;d=(*c&30)>>1;if(*c&1&(d==7|((!(d&1))&(d<6|d>8)))){t+=!v++;}
else v=0;}else v=a=0;}return 206.835-1.*w/s-82.*t/w;}

여기서 논리는 간단한 상태 머신입니다. 문장은 마침표로만, 단어는 알파벳 문자로, 음절은 모음 문자열 (y 포함)로 계산합니다.

나는 올바른 수치를 내기 위해 상수를 조금씩 조정해야했지만, 음절을 단지 소수로 세는 Strigoides의 트릭을 빌렸다.

주석 및 일부 디버깅 도구가 포함 된 Ungolfed

#include <stdlib.h>
#include <stdio.h>
d,a,/*last character was alphabetic */
  v,/*lastcharacter was a vowel */
  s, /* sentences counted by periods */
  t, /* syllables counted by non-consequtive vowels */
  w; /* words counted by non-letters after letters */
float R/*eadability*/(char*c){
  for(;*c;++c){
    s+=*c=='.';
    if(isalpha(*c)){ /* a letter might mark the start of a word or a
               vowel string */
      w+=!a++; /* It is only the start of a word if the last character
              wasn't a letter */
      /* Extract the four bits of the character that matter in determining
       * vowelness because a vowel might mark a syllable */
      d=(*c&30)>>1;
      if( *c&1  & ( d==7 | ( (!(d&1)) & (d<6|d>8) ) ) 
      ) { /* These bits 7 or even and not 6, 8 make for a
         vowel */
    printf("Vowel: '%c' (mangled as %d [0x%x]) counts:%d\n",*c,d,d,!v);
    t+=!v++;
      } else v=0; /* Not a vowel so set the vowel flag to zero */
    }else v=a=0; /* this input not alphabetic, so set both the
            alphabet and vowel flags to zero... */
  }
  printf("Syllables: %3i\n",t);
  printf("Words:     %3i       (t/w) = %f\n",w,(1.0*t/w));
  printf("Sentences: %3i       (w/s) = %f\n",s,(1.0*w/s));
  /* Constants tweaked here due to bad counting behavior ...
   * were:       1.015     84.6 */
  return 206.835-1.   *w/s-82. *t/w;
}
main(c){
  int i=0,n=100;
  char*buf=malloc(n);
  /* Suck in the whole input at once, using a dynamic array for staorage */
  while((c=getc(stdin))!=-1){
    if(i==n-1){ /* Leave room for the termination */
      n*=1.4;
      buf=realloc(buf,n);
      printf("Reallocated to %d\n",n);
    }
    buf[i++]=c;
    printf("%c %c\n",c,buf[i-1]);
  }
  /* Be sure the string is terminated */
  buf[i]=0;
  printf("'%s'\n",buf);
  printf("%f\n",R/*eadability*/(buf));
}

출력 : (긴 버전의 발판을 사용하지만 골프 기능을 사용합니다.)

$ gcc readability_golf.c
readability_golf.c:1: warning: data definition has no type or storage class
$ ./a.out < readability1.txt 
'I would not, could not, in the rain.
Not in the dark, not on a train.
Not in a car, not in a tree.
I do not like them, Sam, you see.
Not in a house, not in a box.
Not with a mouse, not with a fox.
I will not eat them here or there.
I do not like them anywhere!
'
104.074631    
$ ./a.out < readability2.txt
'It was a bright cold day in April, and the clocks were striking thirteen.
Winston Smith, his chin nuzzled into his breast in an effort to escape
the vile wind, slipped quickly through the glass doors of Victory Mansions,
though not quickly enough to prevent a swirl of gritty dust from entering
along with him.
'
63.044090
$ ./a.out < readability3.txt 
'When in the Course of human events, it becomes necessary for one people to
dissolve the political bands which have connected them with another, and to
assume among the powers of the earth, the separate and equal station to
which the Laws of Nature and of Nature's God entitle them, a decent respect
to the opinions of mankind requires that they should declare the causes
which impel them to the separation.
'
-1.831667

결함 :

  • 문장 계산 논리가 잘못되었지만 입력 중 하나에 만 a !또는 a 가 있기 때문에 나는 그것을 멀리 합니다 ?.
  • 단어 계산 논리는 수축을 두 단어로 취급합니다.
  • 음절 계산 논리는 하나의 음절과 동일한 수축을 처리합니다. 그러나 아마도 평균을 초과하여 there계산됩니다 (예 : 2로 끝나고 많은 단어 e가 너무 많이 계산됩니다). 따라서 96.9 % 보정의 상수를 적용했습니다.
  • ASCII 문자 집합을 가정합니다.
  • 나는 모음 감지 인정 것으로 예상 [하고 {명확하게 바로하지 않은.
  • K & R 시맨틱에 대한 많은 의존은 이것을 추악하게 만들지 만 코드 골프입니다.

살펴볼 사항 :

  • 나는 펄을 추적하고 있더라도 두 파이썬 솔루션보다 (순간적으로) 앞서있다.

  • 모음을 감지하기 위해 내가 한 끔찍한 일을 많이하십시오. ASCII 표현을 이진으로 작성하고 긴 버전에서 주석을 읽으면 의미가 있습니다.


"허용 가능한 결과를 얻기 위해 손으로 공식을 약간 변경해야했습니다." 이 나쁜 형태 일.
Joe Z.

1
나는 Strigoides의 리드를 최소한 따랐으며 세 가지 테스트 사례를 합의하기 위해 순전히 임시 조정하기 보다는 텍스트 이해력이 누가 실수를했는지에 따라 조정했습니다 .
dmckee --- 전 운영자 고양이

2

파이썬 202 개 194 188 184 171 167 문자

import re
def R(i):r=re.split;w=len(r(r'[ \n]',i));s=r('\\.',i);y=r('[^aeiou](?i)+',i);return 206.835-1.015*w/(len(s)-s.count('\n'))-84.6*(len(y)-y.count(' ')-2)*.98/w

먼저 공백과 줄 바꿈으로 나눠서 총 단어 수를 얻으십시오.

w=len(r(r'[ \n]',i))

그런 다음 수식. 문장과 음절 수는 한 번만 사용되므로이 표현에 포함됩니다.

문장은 단순히 입력 분할 .이며, 개행은 필터링됩니다.

s=r('\\.',i);s=len(s)-s.count('\n')

음절은 모음이 아닌 입력 분할로 구성되며 공백이 제거됩니다. 이것은 음절의 수를 일관되게 약간 과대 평가하는 것처럼 보이므로 조정해야합니다 (약 .98이 그럴 것 같습니다).

y=r('[^aeiou](?i)+',i);y=len(y)-y.count(' ')-2;

202-> 194 : len(x)-2 보다는 len(x[1:-1]). 불필요한 브래킷을 제거했습니다. 음절 정규식을 대소 문자를 구분하지 않음

194-> 188 : 파일이 이전에 유닉스 파일 형식이 아닌 dos로 저장되어 wc -c개행을 두 문자로 계산했습니다. 으악.

188-> 184 :x for x in ... if x!=... 중간 결과를 저장하고 빼서 불쾌한 것들을 제거하십시오x.count(...)

184-> 171 : 입력 / 출력을 제거하고 기능으로 변환

171-> 167 :len(x)-x.count(...) s를 공식에 삽입


귀하의 답변에는 입력 및 출력 절차가 포함되지 않아도됩니다.
Joe Z.

@JoeZeng 오, 알겠습니다. 그런 다음 함수로 바꾸겠습니다.
Strigoides

1

파이썬 380 자

import re
def t(p):
 q=lambda e: e!=''
 w=filter(q,re.split('[ ,\n\t]',p))
 s=filter(q,re.split('[.?!]',p))
 c=len(w)*1.0
 f=c/len(s)
 return w,f,c
def s(w):
 c= len(re.findall(r'([aeiouyAEIOUY]+)',w))
 v='aeiouAEIOU'
 if len(w)>2 and w[-1]=='e'and w[-2]not in v and w[-3]in v:c-= 1
 return c
def f(p):
 w,f,c=t(p)
 i=0
 for o in w:
  i+=s(o)
 x=i/c
 return 206.835-1.015*f-84.6*x

이것은 다소 긴 솔루션이지만 적어도 3 가지 테스트 사례 중 하나만 있으면 충분합니다.

테스트 코드

def test():
 test_cases=[['I would not, could not, in the rain.\
        Not in the dark, not on a train.\
        Not in a car, not in a tree.\
        I do not like them, Sam, you see.\
        Not in a house, not in a box.\
        Not with a mouse, not with a fox.\
        I will not eat them here or there.\
        I do not like them anywhere!', 111.38, 103.38, 119.38],\
        ['It was a bright cold day in April, and the clocks were striking thirteen.\
        Winston Smith, his chin nuzzled into his breast in an effort to escape\
        the vile wind, slipped quickly through the glass doors of Victory Mansions,\
        though not quickly enough to prevent a swirl of gritty dust from entering\
        along with him.', 65.09, 57.09, 73.09],\
        ["When in the Course of human events, it becomes necessary for one people to\
        dissolve the political bands which have connected them with another, and to\
        assume among the powers of the earth, the separate and equal station to\
        which the Laws of Nature and of Nature's God entitle them, a decent respect\
        to the opinions of mankind requires that they should declare the causes\
        which impel them to the separation.", 3.70, -4.70, 11.70]]
 for case in test_cases:
  fre= f(case[0])
  print fre, case[1], (fre>=case[2] and fre<=case[3])

if __name__=='__main__':
 test()

결과-

elssar@elssar-laptop:~/code$ python ./golf/readibility.py
108.910685484 111.38 True
63.5588636364 65.09 True
-1.06661971831 3.7 True

여기에서 음절 카운터를 사용했습니다- 음절 계산

더 읽기 쉬운 버전이 여기에 있습니다


1
if len(w)>2 and w[-1]=='e'and w[-2]not in v and w[-3]in v:c-= 1단순하지만 좋은 근사치. 나는 그것을 좋아한다.
dmckee --- 전 운영자 고양이

0

자바 스크립트, 191 바이트

t=prompt(q=[]);s=((t[m="match"](/[!?.]+/g)||q)[l="length"]||1);y=(t[m](/[aeiouy]+/g)||q)[l]-(t[m](/[^aeiou][aeiou][s\s,'.?!]/g)||q)[l]*.33;w=(t.split(/\s+/g))[l];alert(204-1.015*w/s-84.5*y/w)

첫 번째 테스트 사례는 112.9를 제공합니다 (정답은 111.4, 1.5 포인트 감소)

두 번째 테스트 사례는 67.4를 제공합니다 (정답은 65.1, 2.3 포인트 감소)

세 번째 테스트 사례는 1.7을 제공합니다 (올바른 답변은 3.7 점, 2.0 포인트 차감)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.