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 시맨틱에 대한 많은 의존은 이것을 추악하게 만들지 만 코드 골프입니다.
살펴볼 사항 :