MTのテンプレートタグで素数判定をやってみた。

  • Posted on
  • by

MT4.1ではopモディファイアが導入されて、かなりプログラムチックなことが出来るようになっています。
そこで、なにかMTでやる意味のまったくない作業をテンプレートで作ってみたくなり、とりあえず素数判定を行うテンプレートを書いてみました。

現在のMTのテンプレートエンジンでは、MTForなどのループから任意のタイミングで抜け出すことが出来ないため、MTSetVarTemplateを再帰的に呼び出すことでループの代用をしています。
そのため、大きな数の判定を行うと馬鹿みたいにメモリを喰いまくります・・・
速度を度外視してアルゴリズムを簡潔にした事もあいまって、実用には耐えられない出来になってしまいました。
家のローカル環境では、大体1000くらいの数までなら耐えられますが、それ以上の素数を判定しようとすると戻ってこなくなります。
まあ、こんなことも出来る、というサンプルになればと思い公開してみます。

<mt:ignore> #setvartemplateを使って関数定義 </mt:ignore>
<mt:setvartemplate name="is_prime">
    <mt:if name="num" op="%" value="$check">
        <mt:ignore> #試し割りで余りが出た場合</mt:ignore>
        <mt:setvar name="check" op="++">
        <mt:if name="num" eq="$check">
            <mt:getvar name="num"> は素数だった!
        <mt:else>
            <mt:ignore> #再帰!!</mt:ignore>
            <mt:getvar name="is_prime">
        </mt:if>
    <mt:else>
        <mt:ignore> #試し割りで割り切れた場合</mt:ignore>
        <mt:getvar name="num"> は <mt:getvar name="check"> で割り切れたので素数じゃなかった!
    </mt:if>
</mt:setvartemplate>
 
<mt:ignore> #ここに判定したい数字を指定 </mt:ignore>
<mt:setvar name="num" value="71">
 
<mt:ignore> #チェック用変数の初期化。変更不可!</mt:ignore>
<mt:setvar name="check" value="2">
 
<mt:ignore>
    #setvartemplateで設定したテンプレートを呼び出す。
    #ついでに余分な空白を削除。 
</mt:ignore>
<mt:getvar name="is_prime" regex_replace="/(^\s*|\s*$)/mg":"">
 
<mt:ignore> #続けていくつか試してみる。 </mt:ignore>
 
<mt:setvar name="num" value="109">
<mt:setvar name="check" value="2">
<mt:getvar name="is_prime" regex_replace="/(^\s*|\s*$)/mg":"">
 
<mt:setvar name="num" value="111">
<mt:setvar name="check" value="2">
<mt:getvar name="is_prime" regex_replace="/(^\s*|\s*$)/mg":"">
 
<mt:setvar name="num" value="113">
<mt:setvar name="check" value="2">
<mt:getvar name="is_prime" regex_replace="/(^\s*|\s*$)/mg":"">

実行結果は以下のようになりました。

71 は素数だった!
109 は素数だった!
111 は 3 で割り切れたので素数じゃなかった!
113 は素数だった!