ログイン
編集不可のページディスカッション情報添付ファイル
"CodeGolf"の差分

MMA
1と36のリビジョン間の差分 (その間の編集: 35回)
2010-10-20 19:23:13時点のリビジョン1
サイズ: 252
編集者: 匿名
コメント:
2010-10-31 19:11:24時点のリビジョン36
サイズ: 7138
編集者: ytoku
コメント:
削除された箇所はこのように表示されます。 追加された箇所はこのように表示されます。
行 2: 行 2:
ゴルフ大会会場

{{{#!c
<<TableOfContents(3)>>

= ゴルフ大会会場 =
/* そんなdefineで大丈夫か? */
/* 一番短いコードを頼む */

== 鶴亀算 ==
=== Before: ===
{{{#!highlight c
#include <stdio.h>

int main(void)
{
  int num,leg,tsuru,kame;
  printf("鶴と亀の数の合計 ? ");
  scanf("%d",&num);
  printf("鶴と亀の足の本数の合計 ? ");
  scanf("%d",&leg);
  kame = (leg - 2 * num) / 2;
  tsuru = num - kame;
  printf("鶴と亀の数の合計 %d\n",num);
  printf("鶴と亀の足の本数の合計 %d\n",leg);
  printf("鶴 %d 羽, 亀 %d 匹\n",tsuru,kame);

  return 0;
}
}}}
=== After: ===
{{{#!highlight c
行 7: 行 33:
s="鶴と亀の",y="足の本数の合計";main(n,l){P"? ",s,y+6)S&n)P"? ",s,y)S&l)P"%d\n%s%s %d\n鶴 %d 羽, 亀 %d \n",s,y+6,n,s,y,l,n*2-l/2,l/2-n);}
}}}
s="鶴と亀の",y="足の本数の合計";main(n,l){P"? ",s,y+6)S&n)P"? ",s,y)S&l)P"%d\n%s%s %d\n鶴 %d 羽, 亀 %d 匹\n",s,y+6,n,s,y,l,n*2-l/2,l/2-n);}
}}}
(187B)

 *ポインタの関係で32bitでないと動かない。intが16bitの環境でも動かない。

 *EUC-JPでないとポインタの演算が合わないのでy+6を書き換える必要アリ。

=== Revised (ytoku): ===
{{{#!highlight c
#define P;printf("%s%s "
#define S y);scanf("%d",
s="鶴と亀の",y="足の本数の合計";main(n,l){P"? ",s,6+S&n)P"? ",s,S&l)P"%d\n",s,y+6,n)P"%d\n鶴 %d 羽, 亀 %d 匹\n",s,y,l,n*2-l/2,l/2-n);}
}}}
(185B)
 * 最後のprintfを分割して"%s%s "部分の省略を図ったのと、Sにy)を取り込んだので、それぞれ1B稼げました。

== PKU 1006 ==
http://poj.org/problem?id=1006
=== Before: ===
{{{#!highlight c
#include <stdio.h>

#define C_PHY 23
#define C_EMO 28
#define C_INT 33

int findpeak(int a, int ca, int b, int cb)
{
    a -= b;
    while (a % cb != 0) {
        a += ca;
    }
    return a+b;
}

int main()
{
    int n;
    for (n = 1; ; n++) {
        int p, e, i, d;
        scanf("%d %d %d %d", &p, &e, &i, &d);
        if (p == -1) break;

        int tmp;
        tmp = findpeak(e, C_EMO, i, C_INT);
        tmp = findpeak(tmp, C_EMO*C_INT, p, C_PHY);

        tmp -= d;
        if (tmp <= 0) tmp += C_EMO*C_INT*C_PHY;
        else if (tmp > C_EMO*C_INT*C_PHY) tmp -= C_EMO*C_INT*C_PHY;

        printf("Case %d: the next triple peak occurs in %d days.\n", n, tmp);
    }
    return 0;
}
}}}
 * golf版にアルゴリズムを合わせてあります
=== After: ===
{{{#!highlight c
main(n,p,e,i,d){for(;scanf("%d%d%d%d",&p,&e,&i,&d),p+1;printf("Case %d: the next triple peak occurs in %d days.\n",n++,(i-d+21251)%21252+1))while((i-p)%23|(i-e)%28)i+=33;}
}}}(171B)

 * ホールインワンは157Bらしい
  * Googleで検索するとそのコードが最上位に出てくるけれどもうちょっと考えたいところ
 * mainの第一引数 == 1 (コマンドライン引数がなければ)

== 四則演算と剰余 ==
=== Before: ===
{{{#!highlight c
#include <stdio.h>

int main(void)
{
    int a, b;

    printf("input two numbers\n");
    scanf("%d%d", &a, &b);
    printf("%d+%d=%d\n", a, b, a + b);
    printf("%d-%d=%d\n", a, b, a - b);
    printf("%d*%d=%d\n", a, b, a * b);
    if (b) {
        printf("%d/%d=%d\n", a, b, a / b);
        printf("%d%%%d=%d\n", a, b, a % b);
    }

    return 0;
}
}}}
=== After: ===
{{{#!highlight c
#define p(x) printf("%d%s%d=%d\n",a,#x,b,a x b);
a;main(b){scanf("%d%d",&a,&b);p(+)p(-)p(*)b&&p(/)b&&p(%)}
}}}
(107B)
 * defineは1つで十分だった。可読性もささやかに向上
 * printf("%d"#x"%d=%d\n",a,b,a x b)として1Bの節約を図ったら、p(%)で%d%%d=...と展開された結果残念なことになった
=== Revised (renda): ===
{{{#!highlight c
#define p(x)printf("%d%s%d=%d\n",a,#x,b,a x b);
a;main(b){scanf("%d%d",&a,&b);p(+)p(-)p(*)b&&p(/)b&&p(%)}
}}}
(106B)
 *p(x)の後のSpaceいらないよね!
  *一応hijiri(x86_64)のgccで通ることは確認。sunやnestだとどうでしょう
   *そうか、気付かなかった...sunでもnestでも通りました
=== Revised (ytoku): ===
{{{#!highlight c
#define p(x)&&printf("%d%s%d=%d\n",a,#x,b,a x b)
a;main(b){scanf("%d%d",&a,&b)p(+)p(-)p(*),b p(/)p(%);}
}}}
(104B)
 *b&&が二回出てくるのが気になって一つの式に納められないか考えたらすんなり

== ICPC2010 インターネット予選 A問題 ==
=== Before: ===
あとで
(1103B)
=== After: ===
{{{{#!highlight c
#define K scanf("%d",
#define I(x)for(x=N;--x;)
#define L(a,b,c)I(i)I(j)if(k[i][j])b=b>a?b:a,c=a<c?a:c;b-=c-1;
N=404;main(c,i,j,l,e,f,g,h,n,d){int k[N][N],m[N],o[N];for(;c;){I(i)I(j)l=k[i][j]=m[j]=o[j]=0;e=g=m[0]=o[0]=(f=h=N)/2;K&c);if(k[e][e]=c){for(;--c;K&d),d/2?i=3-d,j=2-d:(i=d-1,j=d),d=m[n]+i,n=o[n]+j,k[d][n]=m[++l]=d,o[l]=n)K&n);L(i,e,f)L(j,g,h)c=printf("%d %d\n",e,g);}}}
}}}}
(380B)
 *変数名を機械的に振ったところ解読不能になった。
 *cは例によって1以上で初期化される

== 3文字の文字列の反転 ==
=== Before: ===
{{{#!highlight c
#include <stdio.h>

int main(void)
{
    char str[4], rts[4];

    printf("文字列を入力してください ");
    scanf("%3s", str);

    rts[0] = str[2];
    rts[1] = str[1];
    rts[2] = str[0];
    rts[3] = str[3];

    printf("%s %s %s %s \n ", str, rts, str, rts);

    return 0;
}
}}}
(299B)
=== After: ===
{{{#!highlight c
#define P(x);printf("%s ",x);
#define S(i);r[i]=s[2-i]
char str[4],rts[4],*s,*r=rts;main(){P("文字列を入力してください")s=gets(str)S(0)S(1)S(2)P(s)P(r)P(s)P(r)P("\n")}
}}}
(168B)
 *main関数の中にセミコロンが1つもないCのコードである。Pの汎用性は計りしれない
 *グローバル変数は0で初期化される
 *warning: this program uses gets(), which is unsafe.
=== Revised (ytoku): ===
{{{#!highlight c
#define P(x)printf("%s ",x);
#define S(i)r[i]=s[2-i];
char str[4],rts[4],*s,*r=rts;main(){P("文字列を入力してください")P(s=gets(str))S(0)S(1)S(2)P(r)P(s)P(r)P("\n")}
}}}
(166B)
 *最初のstrの表示は反転処理の前に行うことができるので、getsした足でそのまま表示で1文字削減
 *さらに、これによってPとS以外の文が消えたのでセミコロンをマクロの最後において1文字削減
=== Revised (ytoku on the dark side): ===
{{{#!highlight c
#define P(x)printf("%s ",x);
#define S r[i]=s[2-i++]
char str[4],rts[4],*s,*r=rts;i;main(){P("文字列を入力してください")P(s=gets(str))S;S;S;P(r)P(s)P(r)P("\n")}
}}}
(161B)
 *ダークサイドに落ちた結果がこれだよ`\(^o^)/`
 *どうみても動作未定義です。本当にありがとうございました。
=== Revised (ytoku): ===
{{{#!highlight c
#define P(x)printf("%s ",x);
char str[4],rts[4],*s,*r=rts+3;main(){P("文字列を入力してください")for(P(s=gets(str))*s;)*--r=*s++;P(r)P(str)P(r)P("\n")}
}}}
(151B)
 *実は#define Sよりも単純にforの方が短かったという罠(155B)
 *さらにポインタでコピーすることでiが消えました
 *ついでにforの初期化部分に前のPを突っ込んで;を消去

renda/golf

ゴルフ大会会場

鶴亀算

Before:

   1 #include <stdio.h>
   2 
   3 int main(void)
   4 {
   5   int num,leg,tsuru,kame;
   6   printf("鶴と亀の数の合計 ? ");
   7   scanf("%d",&num);
   8   printf("鶴と亀の足の本数の合計 ? ");
   9   scanf("%d",&leg);
  10   kame = (leg - 2 * num) / 2;
  11   tsuru = num - kame;
  12   printf("鶴と亀の数の合計 %d\n",num);
  13   printf("鶴と亀の足の本数の合計 %d\n",leg);
  14   printf("鶴 %d 羽, 亀 %d 匹\n",tsuru,kame);
  15 
  16   return 0;
  17 }

After:

   1 #define P;printf("%s%s "
   2 #define S;scanf("%d",
   3 s="鶴と亀の",y="足の本数の合計";main(n,l){P"? ",s,y+6)S&n)P"? ",s,y)S&l)P"%d\n%s%s %d\n鶴 %d 羽, 亀 %d 匹\n",s,y+6,n,s,y,l,n*2-l/2,l/2-n);}

(187B)

  • ポインタの関係で32bitでないと動かない。intが16bitの環境でも動かない。
  • EUC-JPでないとポインタの演算が合わないのでy+6を書き換える必要アリ。

Revised (ytoku):

   1 #define P;printf("%s%s "
   2 #define S y);scanf("%d",
   3 s="鶴と亀の",y="足の本数の合計";main(n,l){P"? ",s,6+S&n)P"? ",s,S&l)P"%d\n",s,y+6,n)P"%d\n鶴 %d 羽, 亀 %d 匹\n",s,y,l,n*2-l/2,l/2-n);}

(185B)

  • 最後のprintfを分割して"%s%s "部分の省略を図ったのと、Sにy)を取り込んだので、それぞれ1B稼げました。

PKU 1006

http://poj.org/problem?id=1006

Before:

   1 #include <stdio.h>
   2 
   3 #define C_PHY 23
   4 #define C_EMO 28
   5 #define C_INT 33
   6 
   7 int findpeak(int a, int ca, int b, int cb)
   8 {
   9     a -= b;
  10     while (a % cb != 0) {
  11         a += ca;
  12     }
  13     return a+b;
  14 }
  15 
  16 int main()
  17 {
  18     int n;
  19     for (n = 1; ; n++) {
  20         int p, e, i, d;
  21         scanf("%d %d %d %d", &p, &e, &i, &d);
  22         if (p == -1) break;
  23 
  24         int tmp;
  25         tmp = findpeak(e, C_EMO, i, C_INT);
  26         tmp = findpeak(tmp, C_EMO*C_INT, p, C_PHY);
  27 
  28         tmp -= d;
  29         if (tmp <= 0) tmp += C_EMO*C_INT*C_PHY;
  30         else if (tmp > C_EMO*C_INT*C_PHY) tmp -= C_EMO*C_INT*C_PHY;
  31 
  32         printf("Case %d: the next triple peak occurs in %d days.\n", n, tmp);
  33     }
  34     return 0;
  35 }
  • golf版にアルゴリズムを合わせてあります

After:

   1 main(n,p,e,i,d){for(;scanf("%d%d%d%d",&p,&e,&i,&d),p+1;printf("Case %d: the next triple peak occurs in %d days.\n",n++,(i-d+21251)%21252+1))while((i-p)%23|(i-e)%28)i+=33;}

(171B)

  • ホールインワンは157Bらしい
    • Googleで検索するとそのコードが最上位に出てくるけれどもうちょっと考えたいところ
  • mainの第一引数 == 1 (コマンドライン引数がなければ)

四則演算と剰余

Before:

   1 #include <stdio.h>
   2 
   3 int main(void)
   4 {
   5     int a, b;
   6 
   7     printf("input two numbers\n");
   8     scanf("%d%d", &a, &b);
   9     printf("%d+%d=%d\n", a, b, a + b);
  10     printf("%d-%d=%d\n", a, b, a - b);
  11     printf("%d*%d=%d\n", a, b, a * b);
  12     if (b) {
  13         printf("%d/%d=%d\n", a, b, a / b);
  14         printf("%d%%%d=%d\n", a, b, a % b);
  15     }
  16 
  17     return 0;
  18 }

After:

   1 #define p(x) printf("%d%s%d=%d\n",a,#x,b,a x b);
   2 a;main(b){scanf("%d%d",&a,&b);p(+)p(-)p(*)b&&p(/)b&&p(%)}

(107B)

  • defineは1つで十分だった。可読性もささやかに向上
  • printf("%d"#x"%d=%d\n",a,b,a x b)として1Bの節約を図ったら、p(%)で%d%%d=...と展開された結果残念なことになった

Revised (renda):

   1 #define p(x)printf("%d%s%d=%d\n",a,#x,b,a x b);
   2 a;main(b){scanf("%d%d",&a,&b);p(+)p(-)p(*)b&&p(/)b&&p(%)}

(106B)

  • p(x)の後のSpaceいらないよね!
    • 一応hijiri(x86_64)のgccで通ることは確認。sunやnestだとどうでしょう
      • そうか、気付かなかった...sunでもnestでも通りました

Revised (ytoku):

   1 #define p(x)&&printf("%d%s%d=%d\n",a,#x,b,a x b)
   2 a;main(b){scanf("%d%d",&a,&b)p(+)p(-)p(*),b p(/)p(%);}

(104B)

  • b&&が二回出てくるのが気になって一つの式に納められないか考えたらすんなり

ICPC2010 インターネット予選 A問題

Before:

あとで (1103B)

After:

   1 #define K scanf("%d",
   2 #define I(x)for(x=N;--x;)
   3 #define L(a,b,c)I(i)I(j)if(k[i][j])b=b>a?b:a,c=a<c?a:c;b-=c-1;
   4 N=404;main(c,i,j,l,e,f,g,h,n,d){int k[N][N],m[N],o[N];for(;c;){I(i)I(j)l=k[i][j]=m[j]=o[j]=0;e=g=m[0]=o[0]=(f=h=N)/2;K&c);if(k[e][e]=c){for(;--c;K&d),d/2?i=3-d,j=2-d:(i=d-1,j=d),d=m[n]+i,n=o[n]+j,k[d][n]=m[++l]=d,o[l]=n)K&n);L(i,e,f)L(j,g,h)c=printf("%d %d\n",e,g);}}}

(380B)

  • 変数名を機械的に振ったところ解読不能になった。
  • cは例によって1以上で初期化される

3文字の文字列の反転

Before:

   1 #include <stdio.h>
   2 
   3 int main(void)
   4 {
   5     char str[4], rts[4];
   6 
   7     printf("文字列を入力してください ");
   8     scanf("%3s", str);
   9 
  10     rts[0] = str[2];
  11     rts[1] = str[1];
  12     rts[2] = str[0];
  13     rts[3] = str[3];
  14 
  15     printf("%s %s %s %s \n ", str, rts, str, rts);
  16 
  17     return 0;
  18 }

(299B)

After:

   1 #define P(x);printf("%s ",x);
   2 #define S(i);r[i]=s[2-i]
   3 char str[4],rts[4],*s,*r=rts;main(){P("文字列を入力してください")s=gets(str)S(0)S(1)S(2)P(s)P(r)P(s)P(r)P("\n")}

(168B)

  • main関数の中にセミコロンが1つもないCのコードである。Pの汎用性は計りしれない
  • グローバル変数は0で初期化される
  • warning: this program uses gets(), which is unsafe.

Revised (ytoku):

   1 #define P(x)printf("%s ",x);
   2 #define S(i)r[i]=s[2-i];
   3 char str[4],rts[4],*s,*r=rts;main(){P("文字列を入力してください")P(s=gets(str))S(0)S(1)S(2)P(r)P(s)P(r)P("\n")}

(166B)

  • 最初のstrの表示は反転処理の前に行うことができるので、getsした足でそのまま表示で1文字削減
  • さらに、これによってPとS以外の文が消えたのでセミコロンをマクロの最後において1文字削減

Revised (ytoku on the dark side):

   1 #define P(x)printf("%s ",x);
   2 #define S r[i]=s[2-i++]
   3 char str[4],rts[4],*s,*r=rts;i;main(){P("文字列を入力してください")P(s=gets(str))S;S;S;P(r)P(s)P(r)P("\n")}

(161B)

  • ダークサイドに落ちた結果がこれだよ\(^o^)/

  • どうみても動作未定義です。本当にありがとうございました。

Revised (ytoku):

   1 #define P(x)printf("%s ",x);
   2 char str[4],rts[4],*s,*r=rts+3;main(){P("文字列を入力してください")for(P(s=gets(str))*s;)*--r=*s++;P(r)P(str)P(r)P("\n")}

(151B)

  • 実は#define Sよりも単純にforの方が短かったという罠(155B)
  • さらにポインタでコピーすることでiが消えました
  • ついでにforの初期化部分に前のPを突っ込んで;を消去

CodeGolf (最終更新日時 2013-07-24 21:33:54 更新者 ytoku)