「変数変換」という名が適切かは分かりませんが,
「何を文字で置くか」という点で気をつけるべきことがいくつかあるので
整理しておきたいと思います.

ppp…qqq

「a(X,Y):XY**XY*XYa(pX,Yq)」のような形のときには「XY」をひと固まりに考えて
「a(Z):Z**Z*Za(pZq)」のように書くことができます.「育てるものが2種類ある」ときには
それを1つの変数におしこめられないかを考えるとよいでしょう.
上手く区切り方を変えることでこの手法が使える場合もあります.
なるべく「育てるパターンの種類数が少ない」方法を考えるよう心がけましょう.

L字と棒

上述の考え方の代表例として,L字と棒があります.ちなみに私は「sssrsss」というようなものをL字
「sssrrsss」というようなものをと呼んでいます.

L字は「a(X):***a(sX)」という形で「XrX」というものを1単位と数える感じですね.
正方形を描く場合でも「a(X):XrXa(sXs), a(r)」というようにL字を単位として描くこともできます.
L字を単位として描いても縮まない場合もありますが選択肢には入れておくとよいでしょう. 「a(X):***a(sXs), a(r)」「a(X):***a(sXrsl), a()」「a(X):***a(sXlsr), a(rr)」
などのように方向転換も込めてL字を作るとよいこともあります.
なお2箇所につけて育てる分,成長する長さが大きいほどL字の成長はデメリットが大きくなります.
例えば「a(X):XrXXrXa(sssssX), a()」と「a(X):XXa(sssssXsssss), a(r)」では後者の方がbyte数がかさみますね.
もちろんsssssを文字で置けばいいのですが…成長速度が小さいほどL字の利が大きくなります.

次に棒ですね.進行方向と棒の向きの関係や,棒を立てる回数などによっても
最善手が変わるので気をつけましょう(笑)

全部網羅できているかは分かりませんが……棒回りは選択肢がかなり多いので気をつけましょう.

AとlArとrAl

「lprのn回繰り返し」と「pのn回繰り返し」は向きが違うだけです.
したがって,「pのn回繰り返しを育てる」代わりに「lprのn回繰り返しを育てる」
ことで同一の再帰を実現することが出来る場合があります.例えば

a(X):XXXXa(sslsrX)
ra(r)
というコードを考えてみましょう.まず,方向転換を再帰の中に入れると
a(X):rXXXXla(sslsrX)
a(r)
となるのでした.これはさらに
a(X):[rXl][rXl][rXl][rXl]a(sslsrX)
a(r)
と考えることで,変数変換して
a(X):XXXXa(rsslsX)
a(r)
書き換えることができます.もともと「sslsrの繰り返し」と思って組んでいたコードが
「rsslsの繰り返し」として書き直されていることがわかると思います.
このように「pの繰り返し」ではなく「rpl」や「lpr」の繰り返しと認識を改めることで
コードの短縮につながる場合があります.
逆にいうと「繰り返しの単位」を決めつけてしまうと短縮に気付けないことがあるので気をつけてください.
特に経験上,「rssslsを繰り返す」のようなコードは「進行方向が右」と思いこんで,
「r+ssslsrの繰り返し」と考えてしまいやすいので気をつけましょう.


戻る inserted by FC2 system