七行プログラミング

このエントリーをはてなブックマークに追加
497basic.c
12行。7行への道は険しい。仕様は448さんとほぼ同じ。
ただし、RはRUN、QはQUIT、Lは実装せず。
※4行目elseの後ろに半角スペースが1つあります。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define X(c,n,e) if((!strncmp(p,c,n))&&(p+=n)){for(;*p==32;++p);p=(e);}else
int b[65536],f,g,i;static char l[103][80],c[80],*p;I(){return*p-48?atoi(p)?atoi
(p):b[*(short*)p]:atoi(p);}main(){do{gets(l[i=100]);p=l[i];while(i<101){for(;*p
==32;++p);X("\0",1,l[++i])X("GOTO ",5,l[i=I()])X("PUT ",4,(printf("%d\n",I()),l
[++i]))X("GET ",4,(printf("?"),gets(c),b[*(short*)p]=atoi(c),*c=0,l[++i]))X("I\
F ",3,I()?p+3:l[++i])X("RUN",3,l[i=l[100][0]=0])X("QUIT",4,l[i=102])if(*p==48||
atoi(p))strcpy(l[atoi(p)],p+3),++i;else(61-p[2]?puts("ERR"):(p+=3,f=I(),p+=3,g=
I(),--p,b[*(short*)(p-5)]=*p-43?*p-45?*p-42?*p-47?*p-60?*p-62?*p-21?*p-61?*p-37
?f:f%g:f==g:f!=g:f>g:f<g:f/g:f*g:f-g:f+g)),p=l[++i];}puts("OK");}while(i-102);}
498477:01/09/13 18:28
15行で力尽きた。
>>488さんの小手先で短くした版。

#include <stdio.h>
#include <stdlib.h>
int u(char*s,char*r){for(;*r;s++,r++)if(*s-*r)break;return!*r;}int t(char*s){
int r=0;for(;*s;s++,r++);return r;}int b[65536],r,m;char l[100][80],c[80];char*
S(char*s){for(;*s==' ';s++);return s;}int N(char*s){return ((*s>'/'&&*s<':')||
*s=='-')?atoi(s):b[*(short*)s];}int C(char*s){int i=0,f,g=s[0];if(*s)if(u(s,
"GOTO "))r=N(S(s+5))-1;else if(u(s,"PUT "))printf("%d.",N(S(s+4)));else if(u(s,
"? ")){if(s[t(s)-1]==';'){i=1;s[t(s)-1]=0;}printf("%s",s+2);if(i)printf("\n");}
else if(u(s,"IF ")){if(N(s+3))C(S(s+6));}else if(s[2]=='=')f=N(s+3),g=N(s+6),i=
s[5]-43,b[*(short*)s]=i?i-2?i+1?i-4?i-17?i-19?i+22?i-18?i+6?f:f%g:f==g:f!=g:f>g
:f<g:f/g:f*g:f-g:f+g;else if((f=atoi(s))>0||g=='0'){for(i=0;i<t(s+2);i++)l[f][i
]=s[3+i];if(m<f)m=f;}else if(g=='L'){for(;i<=m;i++)if(*l[i])printf("%02d %s\n",
i,l[i]);}else if(g=='R')for(;i<=m;i++)C(S(l[i]));else if(g=='Q')exit(0);else if
(u(s,"GET ")){printf("?");fgets(c,79,stdin);b[*(short*)S(s+4)]=atoi(c);}else
puts("ERR");}main(){for(;;){fgets(c,79,stdin);if(*c){C(S(c));puts("\nOK");}}}
499デフォルトの名無しさん:01/09/13 23:26
スゴイゴイスゴイー
熱い…熱いぜこのスレ!
501名無しさん:01/09/14 01:42
>>497 + >>498
で1行は縮みそうだね

>>498のこれ好きー
>int u(char*s,char*r){for(;*r;s++,r++)if(*s-*r)break;return!*r;}
502デフォルトの名無しさん:01/09/14 06:11
どうせならn行に圧縮したコードと、
インデント付けたソース両方載せて欲しいなぁ・・
503デフォルトの名無しさん:01/09/14 06:13
>>502
indent使えばイージャン
504basic.c:01/09/14 11:00
>>477さん
501さんの指摘した関数は
u(char*s,char*r){for(;*r&&*s!=*r;++r);return!*r;}
または
u(char*s,char*r){while(*r&&*s!=*r)++r;return!*r;}
(どちらもバイト数は同じ)と書けます。
・関数の返り値はintにして省略する。
・1度しか呼ばない関数を定義しない。
・変数は出来るだけグローバルにして同時に宣言。
・if文は出来るだけ使わない(?:を使うためにも関数の型をそろえる
 などは有効)。
・;の代わりに,を使う。
この辺りはIOCCCの1-linerを作るコツと一致します。

>>502さん
私のコードはインデントしても多分無駄です。
一応インデント+適当に括弧をつけて見やすくしました。
行数が多いようなので次に書きます。
505491-495,497,504:01/09/14 11:03
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define X(c,n,e) if((!strncmp(p,c,n))&&(p+=n)){for(;*p==32;++p);p=(e);}else
int b[65536], f, g, i;
static char l[103][80], c[80], *p;
I()
{
 return *p - 48 ?
      ( atoi(p) ? atoi(p) : b[*(short*)p] ):
      atoi(p);
}
main ()
{
 do{
  gets(l[i = 100]);
  p = l[i];
  while (i < 101){
   for (; *p == 32; ++p);
   X("\0", 1, l[++i])
   X("GOTO ", 5, l[i = I()])
   X("PUT ", 4, (printf("%d\n", I()), l[++i]) )
   X("GET ", 4, (printf("?"), gets(c),
           b[*(short*)p] = atoi(c), *c = 0, l[++i]) )
   X("IF ", 3, I()? p+3 : l[++i])
   X("RUN", 3, l[i = l[100][0] = 0])
   X("QUIT", 4, l[i = 102])
   if(*p == 48 || atoi(p)) strcpy(l[atoi(p)], p+3),++i;
   else ( 61 - p[2] ?
506505:01/09/14 11:04
続きです。
        puts("ERR"):
        ( p+=3, f=I(), p+=3, g=I(), --p,
         b[*(short*)(p-5)] =
           *p - 43 ?
             *p - 45 ?
              *p - 42 ?
                *p - 47 ?
                 *p - 60 ?
                   *p - 62 ?
                    *p - 21 ?
                      *p - 61 ?
                       ( *p - 37 ? f: f % g )
                       :
                       f == g
                      :
                      f != g
                    :
                    f > g
                   :
                   f < g
                 :
                 f / g
                :
                f * g
              :
              f - g
             :
             f + g ) ),
      p = l[++i];
  }
  puts("OK");
 }
 while (i - 102);
}
>>504
>u(char*s,char*r){for(;*r&&*s!=*r;++r);return!*r;}
++sが抜けてるよ
508504:01/09/14 12:56
ありがとう、ミスってました。
(新バージョンのバグの一因だった)
さらに関数uは巧く引数をグローバル変数化したほうが全体として短くなります。
509504:01/09/14 13:09
それに!=じゃなくて==だ。
510504:01/09/14 15:28
11行。頭の2行なくてもgcc on Linuxなら通るよ。
#include<stdio.h>
#include<stdlib.h>
int b[65536],f,g,i,n;char *m[]={"GOTO ","PUT ","ET ","IF ","RUN","QUIT"},l[103]
[80],c[80],*p,*q,*r,x;S(){for(;*p==32;++p);}T(){return!U()&&(S()|1);}U(){for(r=
m[n++];*r&&*r==*p;++r)++p;return*r;}I(){g=atoi(p);return*p-48?g?g:b[*(short*)p]
:g;}main(){do{gets(p=l[i=100]);while(i<101){n=0;S();if(*(q=p)==48||atoi(q))for(
p=l[atoi(q)],q+=3;*p++=*q++;)i=101;else p=!*q?l[++i]:T()?l[i=I()]:T()?printf("\
%d\n",I()),l[++i]:T()?printf("?"),gets(c),b[*(short*)p]=atoi(c),*c=0,l[++i]:T()
?(I()?p+3:l[++i]):T()?l[i=l[100][0]=0]:T()?l[i=102]:(61-q[2]?puts("ERR"):(p=q+3
,f=I(),x=p[2]-43,p+=3,g=I(),b[*(short*)q]=x?x-2?x+1?x-4?x-17?x-19?x+22?x-18?x+6
?f:f%g:f==g:f!=g:f>g:f<g:f/g:f*g:f-g:f+g),l[++i]);}puts("OK");}while(i-102);}
511504:01/09/14 15:46
ただし、GOPUTEIRUQUITがQUITの代わりになる、とかの突っ込みなしね。
良く見ると2文字縮まった。後ろ9行のみ。
これもGOTETPUIFがIFの代わりになったりします。
int b[65536],f,g,i,n;char*m[]={"GOTO ","ET ","PUT ","IF ","RUN","QUIT"},l[103][
80],c[80],*p,*q,*r,x;S(){for(;*p==32;++p);}T(){return!U()&&(S()|1);}U(){for(r=m
[n++];*r&&*r==*p;++r)++p;return*r;}I(){g=atoi(p);return*p-48?g?g:b[*(short*)p]:
g;}main(){do{gets(p=l[i=100]);while(i<101){n=0;S();if(*(q=p)==48||atoi(q))for(p
=l[atoi(q)],q+=3;*p++=*q++;)i=101;else p=!*q?l[++i]:T()?l[i=I()]:T()?printf("?"
),gets(c),b[*(short*)p]=atoi(c),*c=0,l[++i]:T()?printf("%d\n",I()),l[++i]:T()?(
I()?p+3:l[++i]):T()?l[i=l[100][0]=0]:T()?l[i=102]:(61-q[2]?puts("ERR"):(p=q+3,f
=I(),x=p[2]-43,p+=3,g=I(),b[*(short*)q]=x?x-2?x+1?x-4?x-17?x-19?x+22?x-18?x+6?f
:f%g:f==g:f!=g:f>g:f<g:f/g:f*g:f-g:f+g),l[++i]);}puts("OK");}while(i-102);}
512チャット:01/09/15 00:08
#include <stdio.h>
#include <conio.h>
#include <winsock.h>
#include <string.h>
main(int a,char**v){WSADATA w;int s[10],i,j,e=0,os,p=0,r;char b[1000],t[100];
u_long g=0;sockaddr_in o;a--;memset(&s,0,sizeof(s));os=sizeof(o);memset(&o,0,
os);e|=WSAStartup(0x202,&w);e|=s[0]=socket(2,1,0);o.sin_family = 2;o.sin_addr.
s_addr = a?inet_addr(v[1]):0;o.sin_port = htons(9314);if(a)e|=connect(s[0],
(sockaddr*)&o,os);else{e|=bind(s[0],(sockaddr*)&o,os);e|=listen(s[0],9);}for(;e
+1;){fd_set f;timeval v= {0, 0};FD_ZERO(&f);for(i=0;i<10;i++){if(s[i])FD_SET(s[
i], &f);}select(0,&f,0,0,&v);for(i=0;i<10;i++){if(s[i]&&FD_ISSET(s[i],&f)){if(a
||i){ioctlsocket(s[i],FIONREAD,&g);r=1000-p;recv(s[i],b+p,r,0);p+=(g>r)?r:g;for
(;*b<=p;memmove(b,b+*b,p-*b),p-=*b){puts(b+1);if(!a){for(j=1;j<10;j++)if(s[j])
send(s[j],b,*b,0);}}}else{for(j=1;j<10;j++)if(!s[j]){s[j]=accept(s[0],0,0);
break;}}}}if(a)if(kbhit()){fgets(t+1,99,stdin);t[*t=strlen(t+1)]='\0';(*t)++;
send(s[0],t,*t,0);}}}
途中でめげたため匿名&終了処理してないチャットです。
513age:01/09/15 11:24
age
514縮め君:01/09/15 13:19
>>511
int b[65536],f,g,i,n;char*m[]={"GOTO ","ET ","PUT ","IF ","RUN","QUIT"},l[103][
80],c[80],*p,*q,*r,x;S(){for(;*p==32;++p);}T(){return!U()&&(S()|1);}U(){for(r=m
[n++];*r&&*r==*p;++r)++p;return*r;}I(){g=atoi(p);return*p-48?g?g:b[*(short*)p]:
g;}main(){do{gets(p=l[i=100]);while(i<101){n=0;S();if((f=atoi(q=p))||*q==48)for
(p=l[f],q+=3;*p++=*q++;i=101);else++i,p=!*q?l[i-1]:T()?l[i=I()]:T()?printf("?")
,gets(c),b[*(short*)p]=atoi(c),l[i]:T()?printf("%d\n",I()),l[i]:T()?(I()?p+3:l[
i]):T()?l[i=*l[100]=0]:T()?l[i=102]:(61-q[2]?puts("ERR"):(p=q+3,f=I(),x=p[2]-42
,p+=3,g=I(),b[*(short*)q]=x-1?x-3?x?x-5?x-18?x-20?x+9?x-19?x+5?f:f%g:f==g:f-g:f
>g:f<g:f/g:f*g:f-g:f+g),l[i]);}puts("OK");}while(i-102);}

小手先の技で18文字縮小…できたかも。自信ない。
sugoi
516504:01/09/17 09:55
>>541さん
18字縮小とはやられました。
5行目は!*q?l[i-1] じゃなくて!*q?l[i] ですね。
下から2行目の 9は 23じゃないでしょうか?よって引き算の値を
43から42に変えても文字数は減らないと思います。
この2つの修正を加えると19字縮小になりますね。
517504:01/09/17 10:00
間違えた。541じゃなくて514。
518504:01/09/17 12:13
>>514さん
駄目です。
atoiを無駄に呼ばない圧縮はOKですが、
!*q?で始まる巨大条件節がp+3を返して次のループに入る場合、変数iの
値が元と異なってしまいます。処理で言うなら、(BASICの)IFの条件が
成立した場合の動作がおかしくなります。

514さんの中で使用可能なのは
*c=0, の省略(5)
atoi() を不要にする(4)

他には
最後の x?で始まる条件節は順序を入れ替えて+=を使用(1)
I()?で始まる条件節の()が不要(2)

で実際は12字縮小ですね。