2012-10-14 15:31:40Morris

[練習] 打出垃圾碼,以 BrainFuck 為例




Background

有一種比賽 IOCCC 國際C語言混亂代碼大賽。

/* == Generated by Matrix67.com == */

     #include      <stdio.h>
   main(t ,_,a)  char*a;{return
 t<1?main(*a,a[-t],"=a-1kj3gnm:q\
ebh_cf*<r.d>i^+?,()[?qzyrjuvcdefg\
h,!kbpolwxs'.t main(")&&a[-t]&&main
(t-1,_,a):t/2?_==*a?putchar(32[a])
  :_%115<36||main(t,_,a+1):main(
    0,t,")?r<gw:?1<3?+<?m:(+b\
      _?1~<3?y(k:?+b:?ns3+:\
        >+{?([my?>.::}+:>\
          +?e)k|ry?)ig:\
            ?:g:k?,:x\
              +^ts")
                ;}

Matrix67 打出了這個神碼,可惜我沒辦法執行。

於是我今天嘗試想要打出最糟糕的代碼。

上面那一串是 brainfuck

#include <stdio.h>
#define R main(s,a+1,ba)
char p[]=">>>>>>>+>>>+>>+>>+>+>+>>>+>>>+>+<<<<<<<<<<<<<<<<<<<<<<++[>>>>>>>>>+>+>>>>+>>>>+>>>>>>\
>+<<<<<<<<<<<<<<<<<<<<<<<<++[>>>>>>>+>+>+>+>>>+>+>>+>+>>+>+>>+>>+<<<<<<<<<<<<<<<<<<<<\
<<<++[>>>>+>>+>+>>>>+>+>>>>+>>>>>>+>+<<<<<<<<<<<<<<<<<<<<<<++[>>>>>>>+>>>+>>+>>+>>>>>\
>+<<<<<<<<<<<<<<<<<<<++[>>>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+<<<<<<<<<<<<<<<<<<<<+\
+[>+>>+>+>+>+>>+>+>+>>+>+>>+>+>+>+>+<<<<<<<<<<<<<<<<<<<-]<-]<-]<-]<-]<-]>>>>>>.>.>.>.\
>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>", buf[1<<9], *bp = buf-1;
main(int s, char*a, int ba) {
    bp<buf&&(a=p)&&(ba=1)&&(bp++)&&(s=0);
    if(!(*a)) return;
    s&&ba<1&&(s+=(*a)==']')&&(s-=(*a)=='[')
    ?main(s,a-(s!=0),ba):(ba=1)&&
    (*a)=='>'?((++bp)&&R):(*a)=='<'?((--bp)&&R):(*a)=='+'?(++*bp|R):
    (*a)=='-'?(--*bp|R):(*a)=='.'?(putchar(*bp)|R):
    (*a)=='['?((*bp)&&main(s-1,a+1,ba)):
    (*a)==']'?((*bp)?main(1,a-1,0):main(s+1,a+1,1)):s>0;
}

之後我也寫了一個生成 brainfuck 的程式

#include <stdio.h>
int main() {
    char s[128];
    int i, j;
    while(gets(s)) {
        int pos = 0;
        int ptr[8];
        for(i = 0; i < 7; i++) {
            int last = i;
            for(j = 0; s[j]; j++) {
                if(s[j]&(1<<i)) {
                    while(last < j+7)
                        printf(">"), last++, pos++;
                    printf("+");
                }
            }
            ptr[i] = last;
            while(last > i+1)
                printf("<"), pos--, last--;
            if(i != 6)
                printf("++[");
        }
        for(i = 5; i >= 0; i--)
            printf("<-]");
        for(i = 0; i < 6; i++)
            printf(">");
        for(i = 0; s[i]; i++)
            printf(".>");
        puts("");
    }
    return 0;
}