K&R c - 188 196 199 199 229 caractères
Avec la spécification modifiée pour spécifier une fonction, je peux obtenir une grande partie de la surcharge c du décompte. Changement également pour utiliser le hack de comptage de syllabes de Strigoides qui est meilleur que mon ajustement de formule et étendu pour faire face au comptage excessif des mots.
Après avoir trouvé un moyen plus court de faire la détection des voyelles, qui était malheureusement basé sur stdchr
, j'ai été incité à en extraire un peu plus de l'abomination bidirectionnelle que j'utilisais pour ne pas avoir à être ennuyeux.
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 logique ici est une simple machine à états. Il compte les phrases par périodes seulement, les mots par chaînes de caractères alphabétiques et les syllabes comme chaînes de voyelles (y compris y).
J'ai dû traîner un peu les constantes pour obtenir les bonnes figures, mais j'ai emprunté le tour de Strigoides consistant à sous-estimer les syllabes par une fraction fixe.
Non golfé , avec des commentaires et quelques outils de débogage:
#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));
}
Sortie: (en utilisant l'échafaudage de la version longue, mais la fonction golfée.)
$ 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
Lacunes:
- La logique de comptage des phrases est erronée, mais je m'en sors car une seule des entrées a un
!
ou un ?
.
- La logique de comptage de mots traitera les contractions comme deux mots.
- La logique de comptage des syllabes traitera ces mêmes contractions comme une seule syllabe. Mais probablement surévalue en moyenne (par exemple,
there
est compté comme deux et de nombreux mots se terminant par e
seront comptés un de trop), j'ai donc appliqué un facteur constant de correction de 96,9%.
- Suppose un jeu de caractères ASCII.
- Je crois que la détection des voyelles admettra
[
et {
, ce qui n'est clairement pas correct.
- Beaucoup de dépendance à la sémantique K&R rend cela laid, mais bon, c'est du golf de code.
Choses à regarder:
Je suis (momentanément) en avance sur les deux solutions python ici, même si je suis à la traîne de Perl.
Obtenez une charge de la chose horrible que j'ai faite pour détecter les voyelles. Cela a du sens si vous écrivez les représentations ASCII en binaire et lisez le commentaire dans la version longue.