C++Guns – RoboBlog

15.08.2010

fucking C

Filed under: Allgemein — Tags: , — Thomas @ 20:08

Bei Lft Craft habe ich den wohl schrecklichsten C Code aller Zeiten gefunden.

char m[9999],*n[99],*r=m,*p=m+5000,**s=n,d,c;main(){for(read(0,r,4000);c=*r;
r++)c-']'||(d>1||(r=*p?*s:(--s,r)),!d||d--),c-'['||d++||(*++s=r),d||(*p+=c==
'+',*p-=c=='-',p+=c=='>',p-=c=='<',c-'.'||write(2,p,1),c-','||read(2,p,1));}

Leute die meinen Style schlecht reden habe einfach keine Ahnung ;)

Und ja, das Ding compiliert wirklich. In den letzten zwei Tage habe ich das mal in lesbares C übersetzt


// m enthaelt den kompletten bf code und den programm pointer
// also programm und daten, so ist es moeglich eine quine zu programmieren
// 0 bis 4999 ist der bf code in plain text
// n und s sind mir noch nicht so ganz klar
// r zeigt auf das aktuelle zeichen im bf code
// p der programm pointer
// d hat irgendwas mit schleifen zu tun
// c das aktuelle zeichen im bf code

char m[9999],*n[99],*r=m,*p=m+5000,**s=n,d,c;

main(){
// Lese maximal 4000 zeichen von stdin
// (was mag passieren wenn der bf code groesser als 4000 zeicen ist
// naja, wird wohl einfach ueberschrieben)
for(read(0,r,4000);c=*r;r++)
{
//c- ']' || (d>1 || (r=*p?*s:(--s,r)) , !d||d--);
if(c == ']')
{
if(d <= 1) { if(*p) { r = *s; } else { --s; } } if(d) d--; } //c- '[' || d++ || (*++s=r), if(c == '[') { if(d == 0) { d++; *(++s) = r; } } //d|| ( if(d == 0) { //*p+=c=='+', if(c == '+') *p += 1; //*p-=c=='-', if(c == '-') *p -= 1; //p+=c=='>',
if(c == '>')
p += 1;

//p-=c=='<'; if(c == '<') p -= 1; //c-'.'||write(2,p,1); if(c == '.') write(2,p,1); //c-','||read(2,p,1); if(c == ',') read(2,p,1); // ) } } }
(Leider geht die Formatierung in WordPress verloren).

Aber jetzt erstmal ein paar Erklärungen. Wenn man sich den Code genauer anschaut, wird man feststellen, dass wohl alle ";" durch "," ersetzt wurden. So kann man mehrere Anweisungen in eine Zeile schreiben.

a = 0, b = a+1, c = a+b;

Weiterhin fällt auf, dass es kein einziges if() gibt. Man kann ein if() durch ein logisches ODER ersetzen:

a || b++;

Der Ausdruckt stimmt so. Normalerweise erwartet man sowas in einer if(), aber es geht auch ohne. Das Programm wird von links nach rechts abgearbeitet.
Ein ODER ist dann wahr, wenn einer von beiden Argumenten wahr ist.

Also wenn a ungleich 0 ist, zählt das als wahr. Aber sagen wir lieber true, spricht sich schöner.
Wenn also a true ist, muss b++ nicht mehr ausgeführt werden.
Ist a hingegen 0, wird b++ ausgeführt.
So einfach kann es sein :)

Dann fallen Sachen wie p+=c=='>' auf. Auch das ist ganz einfach. Der Operator == wird vor += ausgewertet. Wenn also c=='>' ist, ergibt das true, also 1. Dann steht als zweites p+=1 da. Sollte c irgendein anderes Zeichen sein, wird p+=0 ausgeführt.

Folgender Code ist auch noch erwähnenswert

c- '[' || d++ || blubb

Das ist wieder eine geschachtelte if(). In c steht ein Zeichen vom Bf Code. Sollte in C nun das Zeichen '[' stehen, und subtrahiert man nun ein '[', ist das ergebis 0. Unsere if() wird also wahr und der nächste Ausdruck wird in Angriff genommen.

d++ || blubb

Das Problem mit dem ++ sollte ja bekannt sein, bei d++ wird erst d bentuzt, dann um eins erhöht. Bei ++d wird erst d um ein erhöht und dann benutzt. Ist also d gleich 0. Wird d um eins erhöht und dann blubb ausgewetet.

Mit diesem Wissen kann man schon fast den kompletten Code verstehen. Nur diese eine Zeile hat mich eine Weile beschäftigt

c- ']' || (d>1 || (r=*p?*s:(--s,r)) , !d||d--)

Schaut erstmal eine Weile drauf. Am Anfang eine if(), noch eine if(), noch eine if() und dann noh eine if() ;)

Interesannt ist nur der innerste Teil

r=*p?*s:(--s,r)

Da steht ?:
Und ?: geht vor dem = Operator. Wenn also *p nicht 0 ist, dann wird r = *s ausgeführt. Sollte *p 0 ergeben. Wird erst s um eins erniedrigt und dann r=r ausgeführt.
r=r ist natürlich doof, aber ohne das würde da stehen r=--s; und das ist ja nicht gewollt.

So und was ist das nun für ein Programm? Na ein Brainfuck Interpreter. Sieht man doch ;)

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

You must be logged in to post a comment.

Powered by WordPress