สร้างดัชนีการอ่าน


13

Flesch-Kincaid การอ่านขั้นตอนวิธีการขึ้นอยู่กับมาตรการของการนับคำพูดและการนับพยางค์ที่ไม่เป็นไปตามวัตถุประสงค์ทั้งหมดหรือ automatable อย่างง่ายดายโดยใช้คอมพิวเตอร์ ตัวอย่างเช่น "code-golf" ที่มีเครื่องหมายขีดคั่นหรือไม่นับเป็นหนึ่งคำหรือสองคำหรือไม่ คำว่า "ล้าน" เป็นสองหรือสามพยางค์? ในงานนี้คุณจะต้องประมาณค่าเนื่องจากการนับอย่างแน่นอนจะใช้เวลามากเกินไปพื้นที่และที่สำคัญที่สุดคือรหัส

งานของคุณคือการสร้างโปรแกรมที่เล็กที่สุดเท่าที่จะเป็นไปได้ (เช่นฟังก์ชั่น) ในภาษาใด ๆ ที่จะใช้ข้อความการอ่านภาษาอังกฤษ (สันนิษฐานว่าเป็นประโยคที่สมบูรณ์) และคำนวณดัชนีความง่ายดายในการอ่าน Flesch การแปรผันของการนับพยางค์และการนับคำ) มีการคำนวณดังนี้

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 (64 พยางค์ 62 คำใน 8 ประโยค)

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 (74 พยางค์ 55 คำใน 2 ประโยค)

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 (110 พยางค์ 71 คำใน 1 ประโยค)

หากคุณมีข้อความอื่นใดที่คุณได้นับพยางค์และคำด้วยตนเองและคำนวณดัชนีคุณอาจแสดงว่าเป็นการยืนยัน


มันเป็นฟังก์ชั่นได้หรือไม่? หรือว่าต้องใช้ STDIN?
Brigand

2
คุณมีการนับพยางค์สำหรับข้อความตัวอย่าง 3 ข้อความหรือเพียงดัชนี? หากคุณมีมันการนับพยางค์จะเป็นประโยชน์สำหรับการเปรียบเทียบ
Strigoides

มันสามารถเป็นฟังก์ชั่น ในความเป็นจริงมันควรจะเป็นฟังก์ชั่น
Joe Z.

คำตอบ:


6

Perl 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

K&R c - 188 196 199 229ตัวอักษร

ด้วยการเปลี่ยนสเป็คเพื่อระบุฟังก์ชั่นฉันจะได้รับจำนวนมากของค่าใช้จ่ายคออกจากการนับ การเปลี่ยนไปใช้การนับจำนวนพยางค์ของ 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)

ฉันต้องทำให้ค่าคงที่หายไปเล็กน้อยเพื่อให้มันออกมาพร้อมกับตัวเลขที่ถูกต้อง แต่ฉันได้ยืมเคล็ดลับของสไตรโกเดี้ยนว่าควรจะลดจำนวนพยางค์ลงไปเพียงเล็กน้อย

ยกเลิกการตีกอล์ฟพร้อมความคิดเห็นและเครื่องมือแก้ไขข้อบกพร่องบางอย่าง:

#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));
}

เอาท์พุท: (ใช้นั่งร้านจากรุ่นยาว แต่ใช้ฟังก์ชัน golfed)

$ 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

ข้อบกพร่อง:

  • ตรรกะประโยคนับเป็นสิ่งที่ผิด แต่ฉันได้รับไปกับมันเพราะเพียงหนึ่งในปัจจัยการผลิตที่มีหรือ!?
  • ตรรกะการนับคำจะถือว่าการหดตัวเป็นสองคำ
  • ตรรกะการนับพยางค์จะถือว่าการหดตัวเช่นเดียวกับพยางค์เดียว แต่อาจเกินจำนวนเฉลี่ย (ตัวอย่างเช่นthereนับเป็นสองคำและหลายคำที่ลงท้ายด้วยeจะนับหนึ่งมากเกินไป) ดังนั้นฉันจึงใช้ปัจจัยคงที่ของการแก้ไข 96.9%
  • ถือว่าชุดอักขระ ASCII
  • ฉันเชื่อว่าการตรวจจับเสียงสระจะยอมรับ[และ{เห็นได้ชัดว่าไม่ถูกต้อง
  • การพึ่งพาความหมายของ K&R มากมายทำให้เรื่องนี้น่าเกลียด แต่เฮ้มันเป็นรหัสกอล์ฟ

สิ่งที่ต้องดู:

  • ฉันอยู่ข้างหน้าของสารละลายไพ ธ อนทั้งคู่ที่นี่ถึงแม้ว่าฉันจะติดตาม perl อยู่ก็ตาม

  • รับสิ่งที่น่าสยดสยองที่ฉันทำเพื่อตรวจหาสระ มันสมเหตุสมผลถ้าคุณเขียนการแทน ASCII ออกมาเป็นไบนารี่และอ่านความคิดเห็นในเวอร์ชั่นยาว


"ฉันต้องเปลี่ยนสูตรเล็กน้อยด้วยมือเพื่อให้ได้ผลลัพธ์ที่ยอมรับได้" นี่อาจเป็นรูปแบบที่ไม่ดี
Joe Z.

1
ฉันมีตอนนี้ตามอย่างน้อยนำ Strigoides และทำการปรับเปลี่ยนบนพื้นฐานของความเข้าใจที่ข้อความที่ทำให้เกิดข้อผิดพลาดมากกว่าหมดจดเฉพาะกิจบิดแหวนสามกรณีทดสอบลงนามในสัญญา
dmckee --- ผู้ดูแลอดีตลูกแมว

2

Python, 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')

พยางค์ประกอบด้วยการแบ่งอินพุตตามสระที่ไม่ได้มีการลบช่องว่าง ดูเหมือนว่าจะมีการประมาณจำนวนพยางค์ที่มากกว่าเล็กน้อยอย่างต่อเนื่องดังนั้นเราจึงจำเป็นต้องปรับลดลง (ประมาณ 0.98 ดูเหมือนว่าจะทำ):

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

202 -> 194: มากกว่าlen(x)-2 len(x[1:-1])ลบวงเล็บเหลี่ยมที่ไม่จำเป็นออก ทำ regex แบบตัวพิมพ์เล็ก - เล็ก

194 -> 188: ก่อนหน้านี้ไฟล์ถูกบันทึกเป็น dos แทนที่จะเป็นรูปแบบไฟล์ unix ทำให้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

Python 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

Javascript, 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.