3位:colun 様 のコード (210文字)
元のコード
整形コード
for(
v=u=[a=w=x=81];
~a;
x+160
?
0<x--
?
v[x]="_%\n"[
2*!z
|
Math.abs(z-82)<y+y%8
]
:
v[
y=b%78+b%38*w+w
]=
v[
v[++y]="*",
v[y-w]=v[y+w]="|",
y+1
]=
"-"
:
u[a--]=v.join(v=[],x=3239)
)
y=x/w|0,
z=x%w*2,
b=(x-a)*x*49999-5537&65535;
return u
解説付きコード
/*
* 全ての計算を1つのループで回す
*/
for(
v=u=[a=w=x=81]; // v, u を配列として初期化
// (中の値には意味がない)
// a, w, x を81で初期化
~a; // 「~」は、4バイト整数と見なして
// 各ビットを反転させた結果を返す
// 例)
// 81 → -82 → true
// 1 → -2 → true
// 0 → -1 → true
// -1 → 0 → false
// -2 → 1 → true
// つまり a が-1になるまで計算を行う
x+160 // イルミネーション計算の分、160下駄を履かせる
?
/*
* アスキーアートの描画行う
*/
0<x-- // x を減算
?
/*
* x が0より大きい間は背景と木と改行の判定
*/
v[x]="_%\n"[
2*!z // z が0の場合(改行位置)のみ「!z」は
// true(1)になる
// そのため、で2番目の文字「\n」を
// 参照する
// その他の場合は「!z」はfalse(0)
// になる
// そのため「2*0=0」で「|」以降に
// 1が来なければ「_」を参照する
|
Math.abs(z-82)<y+y%8
// z は2刻みで0~160を取る
// 「Math.abs(z-82)」で真ん中から
// 折り返す
// 「y+y%8」で、以下のように増え、
// 元の式と同じになる
// 1+1=2, 2+2=4, 3+3=6, ... 7+7=14,
// 8+0=8, 9+1=10, 10+2=12, ...
]
:
/*
* x が0より小さい場合はイルミネーションの判定
* (ここで160の下駄を履かせたのが生きてくる)
*/
v[
y=b%78+b%38*w+w // イルミネーション
// の位置を計算
]= // 横棒が入る
v[ // 横棒が入る
v[++y]="*", // 中心が入る
v[y-w]=v[y+w]="|", // 縦棒が入る
y+1
]=
"-"
:
/*
* 文字列を結合して配列に格納
*/
u[a--]=v.join(v=[],x=3239)
// join([])で、空文字連結と同じ
// joinの第2引数(使わない場所)を利用して
// 「x=3239」をセット
// 3239 = (横80字+改行1字)×40行-末尾改行1字
// 「u[a--]」配列4つではなく、a=81で設定された
// 数のアスキー後が格納される
)
/*
* 描画に必要な値を計算
*/
y=x/w|0, // y 座標の値
// x/w の浮動小数点数に対してOR演算で0を
// 指定することで、浮動小数点数を整数と
// みなして計算を行い、結果的に整数を作る
z=x%w*2, // z は2刻みで0~160を取る
b=(x-a)*x*49999-5537&65535; // 乱数もどき
// x がマイナスの間だけ、イルミネーション用の
// 変数として使われる。元のコードは「(a+i)*i」
// で正の値を前提としたコード
// このiの位置にマイナスであるxを入れると値が
// おかしくなる
// そこで「(-a+x<負値>)*x<負値>」として、同等の
// 計算が行えるようにする
//
// 0xFFFF = 65535
// 59999-(0x10000)=-5537
// →「+59999 & 0xFFFF」と「-5537 & 0xFFFF」は等価
// 例)0xF = 15 = b1111
// 9 の場合は 9+(0x10) = 9+16 = 25
// 9 の場合は 9-(0x10) = 9-16 = -7
// 10+ 25 & 15 → 35 & 15 →b100011 & b1111 → b11
// 10+ 9 & 15 → 19 & 15 → b10011 & b1111 → b11
// 10- 7 & 15 → 3 & 15 → b11 & b1111 → b11
// マスクする値+1を足したり引いたりした値でも
// 同じ結果になる
return u
同文字数別解
元のコード
整形コード
for(
v=u=[t=z=a=w=81];
a;
t||--z+160
?
v[++t]="*-|"[
(d=
(b=
(a+~z)*z*15537-5537&65535
)
%78+b%38*w+83-t
)
*d<2
?
d&1
:
d*d-6559
]
||
v[t]
||
"_%\n"[
t%w
?
Math.abs(t%w*2-82)
<
(y=t/w|0)+y%8|0
:
2
]
:
u[--a]=v.join(v=[],z=1)
)
t%=3239;
return u