K & R C - 188 196 199 229 caracteres
Con la especificación modificada para especificar una función, puedo obtener gran parte de la sobrecarga de la cuenta. También cambio para usar el hack de conteo de sílabas de Strigoides, que es mejor que mi ajuste de fórmula y se extendió para tratar el conteo excesivo de palabras.
Después de encontrar una forma más corta de hacer la detección de vocales, que lamentablemente se basaba en ello stdchr
, tuve el incentivo de exprimir un poco más de la abominación poco tonta que estaba usando para no tener que ser aburrida.
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;}
La lógica aquí es una máquina de estado simple. Cuenta las oraciones solo por puntos, las palabras por cadenas de caracteres alfabéticos y las sílabas como cadenas de vocales (incluyendo y).
Tuve que manipular un poco las constantes para que saliera con las cifras correctas, pero he tomado prestado el truco de Strigoides de no contar las sílabas por una fracción fija.
Sin golf , con comentarios y algunas herramientas de depuración:
#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));
}
Salida: (usando el andamio de la versión larga, pero la función de golf).
$ 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
Deficiencias:
- La lógica de conteo de oraciones es incorrecta, pero me salgo con la suya porque solo una de las entradas tiene a
!
o a ?
.
- La lógica de conteo de palabras tratará las contracciones como dos palabras.
- La lógica de conteo de sílabas tratará esas mismas contracciones como una sílaba. Pero probablemente los excesos en promedio (por ejemplo,
there
se cuentan como dos y muchas palabras que terminan e
se contarán como demasiadas), por lo que he aplicado un factor constante de corrección del 96.9%.
- Asume un conjunto de caracteres ASCII.
- Creo que la detección de vocales admitirá
[
y {
, lo que claramente no es correcto.
- Mucha confianza en la semántica de K&R hace que esto sea feo, pero bueno, es el código golf.
Cosas a mirar:
Estoy (momentáneamente) por delante de ambas soluciones de Python aquí, incluso si estoy siguiendo el perl.
Obtenga una carga de lo horrible que hice para detectar las vocales. Tiene sentido si escribe las representaciones ASCII en binario y lee el comentario en la versión larga.