カメヲラボ

主にプログラミングとお勉強全般について書いてます

もっと縮めようゼ

id:haru-sさんからのトラバで知りました.
わずか565バイトテトリスのプログラミング解説
7行プログラミングですね.7行プログラミングのマインドってのは,500バイトそこそこで収まるようにソースコードを凝縮するってことだと思います.つまり制限容量に収まってしまえば,最後の詰めは甘くてもまあしかたないかなぁと私は思うのですが,まあ縮みそうなソースコードが転がっていると一応見ておきたい気もします.

とりあえず,テトリスのコードを眺めたところでは明らかに縮みそうな箇所がありますね.パッと目に付いたのは,5行目の

if(l%A)l-=l%A*!Z[l];else for(P+=k++,j=l+=A;--j>A;)

ショートコーダーはelseなんて書かないので,たとえばこんな感じで縮めてやれば良いでしょう.

for(j=l+=l%A?-l%A*!Z[l]:(P+=k++,A);l%A&&--j>A;)

3バイトほど縮みました.とはいえ,これはショートコーディングセオリーに従って単純な書き換えを行っただけです.このコードの構造を見てやると,仕方なくif文を使っているような雰囲気がありますから,真面目にアルゴリズムから考え直せばもっともっと縮むんじゃないでしょうか.興味のある人は是非チャレンジしてみてくだされ.

…というか,元のコードってキーボードの下を押しても右に移動する時があるのだけど仕様でしょうか:D

  • 追記:

上記のコードって間違ってますね^^;ソースをじっくり見ると,かなり工夫してますね.甘く見てました.とはいえ,このコードは必ず縮むと思います.

とりあえず1バイトだけ縮めました

<body onKeyDown=K=event.keyCode><script>X=[Z=[B=A=12]];h=e=K=t=P=0;function Y()
{C=[d=K-38];c=0;for(i=4;i--*K;K-13?c+=!Z[h+p+d]:c-=!Z[h+(C[i]=p*A-Math.round(p/
A)*145)])p=B[i];!t|c+4?c-4?0:h+=d:B=C;for(f=K=i=0;i<4;f+=Z[A+p])X[p=h+B[i++]]=1
if(e=!e){if(f|B){for(l=228;i--;)Z[h+B[i]]=k=1;for(B=[8-[19,32,6,-5,21,9,6][t=++
t%7],0,1,t-6?-A:-1];l--;h=5)if(l%A)l-=l%A*!Z[l];else for(P+=k++,j=l+=A;--j>A;)Z
[j]=Z[j-A]}h+=A}for(i=S="";i<240;X[i]=Z[i]|=++i%A<2|i>228)i%A?0:S+="<br>",S+=X[
i]?"■":"_";document.body.innerHTML=S+P;Z[5]||setTimeout(Y,99-P)}Y()</script>
  • さらに追記:

稲葉さんによればきっちり79文字でなくても良いみたいなので,こんな感じで簡単に短縮できますね.これで562バイト.

…って,コードサイズは改行コードを2バイトで数えるものなのかな?っちゅうか,7行プログラミングでは7行に収まってれば良いのでどうでも良いことなのかも.

<body onKeyDown=K=event.keyCode><script>X=[Z=[B=A=12]];h=e=K=t=P=0;function Y()
{C=[d=K-38];c=0;for(i=4;i--*K;c+=K-13?!Z[h+p+d]:-!Z[h+(C[i]=p*A-Math.round(p/A)
*145)])p=B[i];!t|c+4?c-4?0:h+=d:B=C;for(f=K=i=0;i<4;f+=Z[A+p])X[p=h+B[i++]]=1
if(e=!e){if(f|B){for(l=228;i--;)Z[h+B[i]]=k=1;for(B=[8-[19,32,6,-5,21,9,6][t=++
t%7],0,1,t-6?-A:-1];l--;h=5)if(l%A)l-=l%A*!Z[l];else for(P+=k++,j=l+=A;--j>A;)Z
[j]=Z[j-A]}h+=A}for(i=S="";i<240;X[i]=Z[i]|=++i%A<2|i>228)i%A?0:S+="<br>",S+=X[
i]?"■":"_";document.body.innerHTML=S+P;Z[5]||setTimeout(Y,99-P)}Y()</script>

丸め部分をMath.round使わずにやるのって,昔書いた気がするのだけど思い出せない^^;

  • さらにさらに追記:

改行位置を工夫して560バイト.改行位置を考えるってのは,Code GolfでBase64圧縮する時にやってたのを思い出しました…

<body onKeyDown=K=event.keyCode><script>X=[Z=[B=A=12]];function Y(){C=[d=K-38]
c=0;for(i=4;i--*K;c+=K-13?!Z[h+p+d]:-!Z[h+(C[i]=p*A-Math.round(p/A)*145)])p=B[i
];!t|c+4?c-4?0:h+=d:B=C;for(f=K=i=0;i<4;f+=Z[A+p])X[p=h+B[i++]]=1;if(e=!e){if(f
|B){for(l=228;i--;)Z[h+B[i]]=k=1;for(B=[8-[19,32,6,-5,21,9,6][t=++t%7],0,1,t-6?
-A:-1];l--;h=5)if(l%A)l-=l%A*!Z[l];else for(P+=k++,j=l+=A;--j>A;)Z[j]=Z[j-A]}h
+=A}for(i=S="";i<240;X[i]=Z[i]|=++i%A<2|i>228)i%A?0:S+="<br>",S+=X[i]?"■":"_"
document.body.innerHTML=S+P;Z[5]||setTimeout(Y,99-P)}Y(h=e=K=t=P=0)</script>
  • さらにさらにさらに追記

なんかこんなんみつけました.
http://blog.livedoor.jp/dankogai/archives/50941567.html
これはhtml単体で動くわけじゃないから反則っぽいけど,これを利用すると547バイト.ゴルフ的には542バイトってことですね.ちなみに↑のコードは545バイトじゃなくて547バイト(改行1バイトで552バイト,改行2バイトで558バイト)だと思います.

window.onkeydown=function(e){K=e.keyCode};X=[Z=[B=A=12]];function Y(){C=[d=K-38
]c=0;for(i=4;i--*K;c+=K-13?!Z[h+p+d]:-!Z[h+(C[i]=p*A-Math.round(p/A)*145)])p=B[
i];!t|c+4?c-4?0:h+=d:B=C;for(f=K=i=0;i<4;f+=Z[A+p])X[p=h+B[i++]]=1;if(e=!e){if(
f|B){for(l=228;i--;)Z[h+B[i]]=k=1;for(B=[8-[19,32,6,-5,21,9,6][t=++t%7],0,1,t-6
?-A:-1];l--;h=5)if(l%A)l-=l%A*!Z[l];else for(P+=k++,j=l+=A;--j>A;)Z[j]=Z[j-A]}h
+=A}for(i=S="";i<240;X[i]=Z[i]|=++i%A<2|i>228)i%A?0:S+="<br>",S+=X[i]?"■":"_"
document.body.innerHTML=S+P;Z[5]||setTimeout(Y,99-P)}Y(h=e=K=t=P=0)
  • (さらに)^4追記

ショートコーダーはelseなんて書かねーんだヨ!!の箇所を修正しました.htm単体動作版では552バイト(7行ルール&改行1バイト),ゴルフルール(改行無視)では548バイト.フォームに組み込むパターンでは541バイト.まだまだイケるハズ!

<body onKeyDown=K=event.keyCode><script>X=[Z=[B=A=12]];function Y(){C=[d=K-38]
c=0;for(i=4;i--*K;c+=K-13?!Z[h+p+d]:-!Z[h+(C[i]=p*A-Math.round(p/A)*145)])p=B[i
];!t|c+4?c-4?0:h+=d:B=C;for(f=K=i=0;i<4;f+=Z[X[p=h+B[i++]]=A+p]);if(e=!e){if(f|
B){for(l=228;i--;)Z[h+B[i]]=k=1;for(B=[8-[19,32,6,-5,21,9,6][t=++t%7],0,1,t-6?-
A:-1];l--;h=5)for(j=l+=(Q=l%A)?-l%A*!Z[l]:(P+=k++,A);!Q*j>A;)Z[--j]=Z[j-A]}h+=A
}for(i=S="";i<240;X[i]=Z[i]|=++i%A<2|i>228)i%A?0:S+="<br>",S+=X[i]?"■":"_"
document.body.innerHTML=S+P;Z[5]||setTimeout(Y,99-P)}Y(h=e=K=t=P=0)</script>
window.onkeydown=function(e){K=e.keyCode};X=[Z=[B=A=12]];function Y(){C=[d=K-38
];c=0;for(i=4;i--*K;c+=K-13?!Z[h+p+d]:-!Z[h+(C[i]=p*A-Math.round(p/A)*145)])p=B
[i];!t|c+4?c-4?0:h+=d:B=C;for(f=K=i=0;i<4;f+=Z[X[p=h+B[i++]]=A+p]);if(e=!e){if(
f|B){for(l=228;i--;)Z[h+B[i]]=k=1;for(B=[8-[19,32,6,-5,21,9,6][t=++t%7],0,1,t-6
?-A:-1];l--;h=5)for(j=l+=(Q=l%A)?-l%A*!Z[l]:(P+=k++,A);!Q*j>A;)Z[--j]=Z[j-A]}h
+=A}for(i=S="";i<240;X[i]=Z[i]|=++i%A<2|i>228)i%A?0:S+="<br>",S+=X[i]?"■":"_"
document.body.innerHTML=S+P;Z[5]||setTimeout(Y,99-P)}Y(h=e=K=t=P=0)