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
Cronus Crown(クロノス・クラウン)のトップページに戻る
(c)2002-2024 Cronus Crown (c)1997-2024 Masakazu Yanai
ご意見・お問い合わせはサイト情報 弊社への連絡までお願いします
個人情報の取り扱い、利用者情報の外部送信について