多変数による繰り返し

いきなりですが次のコードを見てみましょう:

a(X):XXXXrXXXXa(sX)
a(r)
use_Y_1.png

16byteで2重の正方形を回りながら描きますね.
これを2倍関数により解消しても, 実は短縮にはなりません.

f(X):XX
a(X):f(f(XX)r)la(sX)
a(r)

これだと17byteでかえってbyte数が増えてしまっています.

もう少し工夫した2倍関数の利用により, 同byte数の16byteで動きを再現することは可能です.

f(X):XrX
a(X):f(f(f(X))r)a(sX)
a()

よりよい方法を考えましょう.
再帰の一部ではなく, 次のような状況ならどうするでしょうか?

ssssrssss

これならわざわざ2倍関数を定義する人は少ないと思います.
このときは, 2回出てくる「ssss」または4回出てくる「ss」を文字で置いて

y:ssss
yry

のようにすれば短縮になりますね. 2倍関数の利用よりも短くなります.


実は同じようなことを再帰の一部でも使うことができます.
具体的には次のようなコードで1byteの短縮に成功しています.
(実は最初のコードと少し向きが違うものを描くのですが...見逃してください. )

a(X,Y):YrYa(sX,XXXX)
a(r,)
use_Y_2.png

まさに, Y=XXXXとして, XXXXを他の文字で置いているのが分かりますよね.
他にもXYXやXllXなどを他の文字で置くことにより短縮につながることがあります.

もちろんn倍関数などを使うのが有利な場合もあるので,
(いつも書いているけど)色んな方法を念頭に置くようにしてください.


この方法にはいくつか注意点があります.
これはこの方法を使うときのリスクであるとともに, 裏を返せば
「この方法だからこそ書けるコード」に繋がる可能性もあります.

まずは, 「何段階目か」がずれるということです.
先ほどのコードでは,再帰の「YrY」の部分はとして実行されるものは次のようになります:

1段階目:r

2段階目:[rrrr]r[rrrr]

3段階目:[srsrsrsr]r[srsrsrsr]

4段階目:[ssrssrssrssr]r[ssrssrssrssr]

2段階目のYに1段階目のXが代入されるため, 1段階目の実行では1段階目のXは反映されていないのです.
これが先ほど述べた

実は最初のコードと少し向きが違うものを描く

ことの理由ですね.

つまり1段階目のYは, ある意味で使われていないのです.
実はここを有効利用することもできます(特殊な初項の講でも説明する予定です). 例えば

a(X,Y):YrYa(sX,XXXX)
a(r,sss)

などと実行してみてください.

use_Y_3.png

1段階目:[sss]r[sss]

2段階目:[rrrr]r[rrrr]

3段階目:[srsrsrsr]r[srsrsrsr]

4段階目:[ssrssrssrssr]r[ssrssrssrssr]

と実行されていくのが分かると思います. 初期位置を調整しながら再帰を実行し始めるような場合に,
「YrY」という関数に好きなものを代入する形で使うことができます.
過去にも少ないですがここを利用した短縮がありました.


次の注意点を述べましょう. 例えば

a(X):XXrXXrXXrXa(sX)
a()

というコードを見てみましょう. 「XXr」が多量に含まれるためにそこを文字で置いて

a(X,Y):YYYXa(sX,XXr)
a(,)

としたくなる場面ですね. 実はこれではズレてしまいます.

n段階目の「Y」は, n-1段階目のXを用いた「XXr」である

ためです.

このように中途半端に他変数Yに預けると, XそのものとYで成長速度に差が出るのです.
「わざと差をつける」ことで巧妙な短縮が出来る場面もあるのでテクニックとして
覚えておくとよいですが, 慣れないうちは間違えやすいので気をつけてください.
なおこのことを(3倍関数などを使わず)解消するに, Xも成長速度を遅らせる方法もあります.

a(X,Y,Z):YYYZa(sX,XXr,X)
a(,,)

なお,実は上のコードは

a(X,Y):YYYXa(sX,XrX)
a(,)

を実行したものと同じになります. この理由も考えてみると面白いかもしれません.


添付ファイル: fileuse_Y_3.png 88件 [詳細] fileuse_Y_2.png 92件 [詳細] fileuse_Y_1.png 95件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-01-18 (金) 00:44:19 (2042d)