c - 424 notwendiges Zeichen
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define O(X) g=o();g=o() X g;u(g);break;
char*p=NULL,*b;size_t a,n=0;float g,s[99];float o(){return s[--n];};
void u(float v){s[n++]=v;};int main(){getdelim(&p,&a,EOF,stdin);for(;;){
b=strsep(&p," \n\t");if(3>p-b){if(*b>='0'&&*b<='9')goto n;switch(*b){case 0:
case EOF:printf("%f\n",o());return 0;case'+':O(+)case'-':O(-)case'*':O(*)
case'/':O(/)}}else n:u(atof(b));}}
Angenommen, Sie haben eine neue Libc, die getdelimin stdio.h aufgenommen werden kann. Der Ansatz ist direkt, die gesamte Eingabe wird in einen Puffer eingelesen, dann wird mit der strsepLänge und dem Anfangszeichen getoken und die Klasse der einzelnen Zeichen bestimmt. Es gibt keinen Schutz vor schlechten Eingaben. Füttere es mit "+ - * / + - ...", und es wird fröhlich "unter" dem Stapel Zeug aus dem Speicher entfernen, bis es einen Fehler aufweist. Alle Nicht-Operatoren werden als Gleitkommazahlen interpretiert, atofwas bedeutet, dass der Wert Null ist, wenn sie nicht wie Zahlen aussehen.
Lesbar und kommentiert:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *p=NULL,*b;
size_t a,n=0;
float g,s[99];
float o(){ /* pOp */
//printf("\tpoping '%f'\n",s[n-1]);
return s[--n];
};
void u(float v){ /* pUsh */
//printf("\tpushing '%f'\n",v);
s[n++]=v;
};
int main(){
getdelim(&p,&a,EOF,stdin); /* get all the input */
for(;;){
b=strsep(&p," \n\t"); /* now *b though *(p-1) is a token and p
points at the rest of the input */
if(3>p-b){
if (*b>='0'&&*b<='9') goto n;
//printf("Got 1 char token '%c'\n",*b);
switch (*b) {
case 0:
case EOF: printf("%f\n",o()); return 0;
case '+': g=o(); g=o()+g; u(g); break;
case '-': g=o(); g=o()-g; u(g); break;
case '*': g=o(); g=o()*g; u(g); break;
case '/': g=o(); g=o()/g; u(g); break;
/* all other cases viciously ignored */
}
} else { n:
//printf("Got token '%s' (%f)\n",b,atof(b));
u(atof(b));
}
}
}
Validierung:
$ gcc -c99 rpn_golf.c
$ wc rpn_golf.c
9 34 433 rpn_golf.c
$ echo -4 5 + | ./a.out
1.000000
$ echo 5 2 / | ./a.out
2.500000
$ echo 5 2.5 / | ./a.out
2.000000
Heh! Muss irgendetwas damit zitieren *...
$ echo "5 1 2 + 4 * 3 - +" | ./a.out
14.000000
$ echo "4 2 5 * + 1 3 2 * + /" | ./a.out
2.000000
und mein eigener Testfall
$ echo "12 8 3 * 6 / - 2 + -20.5 " | ./a.out
-20.500000
~. :-P