第5回 mixC Code Golf 感想

アバター
五反田
記事: 21
登録日時: 15年前
住所: 千葉

第5回 mixC Code Golf 感想

投稿記事 by 五反田 » 14年前

問題は↓参照
http://dixq.net/mixC/communityTopic/12

結果発表は↓
http://dixq.net/mixC/diary/495

最短と思われるコード(55B)

CODE:

s;main(i){for(gets(&i);i%=48;puts(memset(&s,35,i--)));}
この一週間ほとんどずっとこれのことが頭から離れなくて、いろいろなコードを書いたので、その感想を書いていきたいと思います。

とりあえず、考えの変遷みたいなものをつらつらと書いていこうかと。

最初はコレを送らせてもらいました。
11月5日(金曜)11時頃(64B)

CODE:

i;main(a){for(scanf("%d",&a);i0);}
正直、中間発表がなければここで自分の記録は止まっていたと思われます。この時は完全にもう無理だって感じになっていたので、まさかこれより3Bも短いコード中間発表で出てくるとは思ってませんでした。

その後はずっと、このことが頭から離れず、授業中にもノートに書いたり、文字コードから1つの演算子と1桁の数字だけで数字を取り出せないかを考えたりしてました。丁度大学の図書館に「Short Coding」があったのを思い出したのですが、図書館のサイトを訪れても返却予定日は10月だよ、ということしか教えてくれず、「誰だよ借りっぱなしの奴は。」などと悪態を心のなかで付いていました。

で、いろいろと考えて、配列に文字をつっこんでそれを再帰で表示させるようなコードを書けました。11日の朝のことです。(61B)

CODE:

char s[9];main(i){gets(&i);s[i%=49]=35;i--&&main(i);puts(s);}
いま考えると、宣言はchar s[]で良かったような気がします。
それから、たぶんですが一桁の数字しか受け取る必要がなくて、その変数を評価する場所があるなら、scanfやgetcharを使うよりもgetsのほうが短くなるのではないでしょうか。

CODE:

scanf("%d",&i);
i=getchar()-48;
gets(&i);i%=48
ここで3行目の;はiを評価する部分に付けてもらいます。または上の例のようにつけなくてすむ所に放りこみます。またgetcharはmain再帰ではEOFを返すので、うまく使えませんでした。
//11/12 13:14分追記
EOFをうまく利用したコードを一番最後に載っけときました。
最短ではありませんが、EOFにも使い方がありそうな気がします。

木曜日に運よくShort Codingが返却されていたのですが、残り少ない時間で読んでもヒントが得られるかどうかは微妙な内容でした。さらっと読んで効果が出せるほど汎用的な手法は、導入しきった気がしたからです。

そして、ついに金曜の夕方、眠気に襲われながらの電車の中でmemsetを思いつきました。「そういえば、memsetって返り値なんだっけ?」と思った自分を誰か褒めて欲しいです。3日ぐらい前にmemsetで縮めようと組み込んでみたのですが、その時は全然縮まらなくて、「関数名長いから使ったのに、やっぱりただの役立たずだったか」などと思ってしまった自分を悔い改めなければなりません。
で、金曜の夜にこんなふうになり(59B)

CODE:

s[3];main(i){for(scanf("%d",&i);i;puts(memset(s,35,i--)));}
「他の人もこれを投稿したのだろうか」とか「1位1番乗りしたかったな」とか思いつつ送りました。
s[3]はint配列ですが、これはchar12個分で、アクセス違反でruntime errorが出ないように確保したものだったのですが、s[]でも通ることが分かって1B縮まり、さらにgetsを使ったことでもう1B縮めることが出来ました。(そのコードは今日投稿したものであるのが悔やまれます)
memsetバンザイ。

という感じです。自分としてはscanfを使っていると、どうも1桁というところを生かしきれていない気がしていたので、そこも含めて満足のいく結果となりました。
途中で、もう60文字ぐらいなら、ループ回してコードを出力すればいつか最短に辿りつくだろう等と思ったりしましたが、とんでもない数になりそうなのですぐには無理だと諦めました。

えーと、ついでに自分の書いたコードの残骸を残ってるものだけ表示したいと思います。全部通るはずのコードです。
あまり長いものは残していないです。

CODE:

i;main(a){for(scanf("%d",&a);i0);}//62B
a;main(i){for(i=(a=getchar()-48)*a;i--;)printf("#%c",10|i%a>0);}//64B
a;main(i){for(i*=i*=a=getchar()-48;i--;)printf("#%c",10|i%a>0);}//64B
i,a;main(){scanf("%d",&a);i0));}//65B
char s[9],i;main(){scanf("%d",&i);s[--i]=35;i&&main();puts(s);}//63B
char s[9];main(){gets(s);s[*s%48]=35;--*s%48&&main();puts(s+1);}//64B
char s[9];main(){scanf("%d",s);s[*s]=35;--*s&&main();puts(s+1);}//64B
char s[9];main(i){gets(&i);s[i%=49]=35;i--&&main(i);puts(s);}//61B
char s[9];main(){gets(s);s[--*s%48]=35;*s-35&&main();puts(s);}//62B
i;main(a){for(gets(&a);i++/a0);}//62B
s[3],i;main(){scanf("%d",&i);s[--i/4]|=35<<i*8;i&&main();puts(s);}//66B
s[];main(i){for(scanf("%d",&i);i;puts(memset(s,35,i--)));}//58B
i,s[3];main(){i+=getchar()%48;i&&main(puts(memset(s,35,i)));}//61B
s[];main(i){for(gets(&i);i%=48;puts(memset(s,35,i--)));}//56B
最後に編集したユーザー 五反田 on 2010年11月14日(日) 11:26 [ 編集 1 回目 ]

アバター
あーる@Reputeless
記事: 84
登録日時: 15年前

Re: 第5回 mixC Code Golf 感想

投稿記事 by あーる@Reputeless » 14年前

涙ぐましい努力が・・・ (´;ω;` ぶわっ
ちなみに僕が最初考えていたのは こういうの(59B)
s[];main(n){for(memset(s,35,n=atoi(gets(s)));n--;)puts(s);}

「Short Coding」いつか読んでみたいです...!
ってかコミュ主がこんなで大丈夫か?

アバター
五反田
記事: 21
登録日時: 15年前
住所: 千葉

Re: 第5回 mixC Code Golf 感想

投稿記事 by 五反田 » 14年前

>>あーるさん
考えるのが非常に楽しかったです。ありがとうございました。

やはり、みなさん一行ずつ表示していくスタイルに落ち着くみたいですね。
自分の場合は、あきらかに自分より短いコードが存在するとわかったお陰で縮めることが出来たので、独力でたどり着く発想力も大事だと思います。

(あーるさんがコミュ主で)いいんじゃないかな。
あーるさんはこんないい問題も提供してくれてるしね。