サンタのためのコードゴルフ

CodeIQアホな素敵な企画をやっていたので参加。
1回目の「最短コードを書く!」は円状のアスキーアートを出力する問題。
2回目の「もしもエンジニアがサンタだったら」はツリー上のアスキーアートを出力する問題。

1回目に提出したコードはこれ(75文字)

for(w='',x=y=z=40;y+z;)w+="-*\n"[x+z?0|x*x--+y*y<900:(x=z,y-=2,2)];return w

2回目に提出したコードはこれ(215文字)

for(a=c=k=y=t=z='',b=[],i=h=40;j=y%8+y>>1,r=(a+k)*k*49999-5537&65535,v=r%38-y+1,w=r%78-h+i+1,a<4;)
h+i?k++<160?z=v*v+w*w<2?v?4:w?2:6:z:(c+="_%--||**"[z|i*i--<j*j],k=z=0):
(i=h,++y<h?c+='\n':(b[a++]=c,c=y=''));return b

ゴルフといえばPEゴルフしかやったことなく割と初心者。
1回目は最短タイ、2回目は5位でなかなか楽しめた。

オフラインイベントにも参加してきた。全員がサンタ帽かぶってコードゴルフしてる横でへそだしサンタと写真撮影という愉快なイベントだった。ここではドーナツ状のアスキーアートを出力する問題が出題されてこれを回答。

for(h=x=y=48,r="";z=x*x+y*y,h+y;)r+=h+x--?z<256?2:0|z<1024:(x=h,y-=2,"\n");return r

83文字で制限時間内ではトップだったが、すぐ縮みそうみたいな5位っぽさを発揮してきた。その後twitterで@notfuncさんが縮めてくれたので、それを77文字まで縮めた。

for(h=x=y=48,r="";h+y;r+=h+x--?!z+(z<4):(x=h,y-=2,"\n"))z=x*x+y*y>>8;return r

出題者の柳井氏が詳細に解説してくれたが、JavaScriptコードゴルフはなかなか奇天烈だったのでメモ。

  1. 2重以上のforループは1重に変換できる
  2. カンマでつなげばforの中だけで処理できる
  3. 演算子の優先順位とにらめっこ
  4. ifを3項演算子
  5. ビット演算子は短いので有用
  6. 59999≡-5537 (mod 1<<16) ※ ビット演算だと余りが必ず正になる

〜 この辺からJavaScript

  1. セミコロンは省略可能なことがある
  2. varをつけない代入文でグローバル変数が作れる(=短い)
  3. 色んな場所でグローバル変数が作れる
    例: a=[i=4]
  4. 型が異なるもの同士の演算は暗黙の型変換が行われる
    例: 文字列に数値100を足すと、'100'が足される
  5. 数値でないものを数値として扱うとゼロ(初期化や評価に使える)
    例: a='',++a → aは1
  6. Booleanは加減乗除やビット演算すれば数値化できる
    例: c+="ab"[0|a==b]
  7. ビット演算で浮動小数点を整数化できる
  8. 素数1以下の配列は数値として扱える(これは驚き...)
    例: a=[4],a+=1 → aは5

柳井さんありがとうございました。
JavaScript面白い!