K&R c - 188 196 199 229 znaków
Po zmianie specyfikacji w celu określenia funkcji mogę uzyskać dużo c narzutu z licznika. Zmieniłem się również, aby użyć hakerskiego liczenia sylab Strigoidesa, co jest lepsze niż moje ulepszenie formuły i rozszerzone, aby poradzić sobie z przeliczaniem słów.
Po tym, jak znalazłem krótszy sposób na wykrycie samogłoski, na którym niestety opierałem się stdchr
, miałem motywację, aby wycisnąć jeszcze więcej z nieco kręcącej się obrzydliwości, której używałem, aby nie musiałem się nudzić.
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;}
Logika tutaj jest prostą maszyną stanu. Zlicza zdania według kropek, słowa według ciągów znaków alfabetycznych, a sylaby jako ciąg samogłosek (w tym y).
Musiałem trochę podważyć stałe, aby uzyskać właściwe liczby, ale pożyczyłem sztuczkę Strigoidesa polegającą na tym, że nie doceniłem sylab o ustalony ułamek.
Bez golfa , z komentarzami i niektórymi narzędziami do debugowania:
#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));
}
Wyjście: (przy użyciu rusztowania z długiej wersji, ale funkcja gry w golfa).
$ 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
Niedociągnięcia:
- Logika liczenia zdań jest niepoprawna, ale mi się to udaje, ponieważ tylko jedno z wejść ma a
!
lub a ?
.
- Logika liczenia słów potraktuje skurcze jako dwa słowa.
- Logika zliczania sylaby potraktuje te same skurcze jak jedną sylabę. Ale prawdopodobnie przecenia się średnio (na przykład
there
liczy się jako dwa, a wiele słów kończących się e
będzie liczonych o jeden za dużo), więc zastosowałem stały współczynnik korekty 96,9%.
- Zakłada zestaw znaków ASCII.
- Wierzę, że wykrywanie samogłoski się przyzna
[
i {
co oczywiście nie jest właściwe.
- Wiele zależności od semantyki K&R sprawia, że jest to brzydkie, ale hej, to jest golf golfowy.
Rzeczy do zobaczenia:
Jestem (chwilowo) przed obydwoma rozwiązaniami w Pythonie, nawet jeśli śledzę perla.
Zdobądź mnóstwo okropnych rzeczy, które zrobiłem dla wykrywania samogłosek. Ma to sens, jeśli zapisujesz reprezentacje ASCII w formacie binarnym i czytasz komentarz w długiej wersji.