5位:hotpepsi 様 のコード (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
解説付きコード
for(
a=c=k=y=t=z='', // 変数を初期化
b=[], // 戻り値用の配列を初期化
i=h=40; // 40で初期化
j=y%8+y>>1, // 「y>>1」で整数演算の「÷2」と同じ
// 「y+y%8」で、以下のように増え、
// 元の式と同じになる
// 1+1=2, 2+2=4, 3+3=6, ... 7+7=14,
// 8+0=8, 9+1=10, 10+2=12, ...
r=(a+k)*k*49999-5537&65535, // 乱数もどき
// 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を足したり引いたりした値でも
// 同じ結果になる
v=r%38-y+1, // 「r%38+1」から y を引いて中心からの距離
w=r%78-h+i+1, // 「r%78+1」から「h-i」(40-i)(iは40から始
// まるので、0, 1, 2...と推移)を引いて
// 中心からの距離
a<4; // aが4未満まで(配列数だけ)ループを回す
)
h+i // h は固定値40、i は40から開始され減算されていく
// そのため「40+i」が0になるまでがアスキーアートで
// 0で改行と、戻り値用配列の遷移
?
/*
* アスキーアートの処理
*/
k++<160 // イルミネーションを調べる
?
/*
* イルミネーションの判定
*/
z=
v*v+w*w<2 // 中心からの距離が2未満
?
/*
* イルミネーションが存在
*/
v // 縦方向の確認
?
4 // 0でない「|」である
:
w // 横方向の確認
?
2 // 0でない「-」である
:
6 // v, w 共に0なので「*」
:
/*
* イルミネーションでないので
* 直前の z の値をそのまま維持する
*/
z
:
/*
* 文字列を参照して結合
*/
(
c+="_%--||**"[
z // イルミネーションの文字列参照位置
// 値は2(b10)、4(b100)、6(b110)
// なので、下の式で1が来た場合には
// 参照位置が1つ右にずれる
// なので「--||**」と2文字ずつある
|
i*i--<j*j // 中心位置からの距離の比較
// i は0を中心に対称に広がる2乗で
// 負の符号を相殺して、jの2乗と比較
// 距離がjの範囲内なら1、外なら0
],
k=z=0 // イルミネーション系変数を初期化
// k カウント
// z 文字列参照位置
)
:
/*
* アスキーアート以外の処理
*/
(
i=h, // 横ライン移動用のiを40で初期化
++y<h // yが40行以内か確認
?
c+='\n' // 40行以内なので改行を追加
:
(
b[a++]=c, // 文字列を配列に格納し
// 対象配列を次に移行
c=y='' // c を空文字で初期化
// y を空文字(0)で初期化
)
);
return b