2016年3月11日金曜日

キヨシ関数のはなし

一部で話題のキヨシ関数をTeXで実装してみたので覚えも兼ねて記事にしてみます
カウンタとかif文やらloop文やらのいい練習になったと思う
↓コレ

ソースがこちら

1 \documentclass{article}
2 \usepackage{lcg}
3 \newcount\rnd                \newcount\KYScountZ        \newcount\KYScountD
4 \def\Kiyoshi{%
5        \rnd=\the\time        \KYScountZ=0                   \KYScountD=0%
6        \loop%
7                \chgrand[seed=\rnd] \rand \rnd=\arabic{rand} %乱数
8                \ifodd\rnd %奇数の時
9                        ズン\par%
10                        \advance\KYScountZ1\relax%
11                \else        %偶数の時
12                        ドコ\par%
13                        \ifnum\KYScountZ>3\relax%%ズン×4以上の時
14                                 キ・ヨ・シ!\par%
15                                \advance\KYScountD1\relax%
16                        \else %%ズンリセット
17                                \KYScountZ=0\relax%
18                        \fi
19                \fi
20                \advance\rnd1\relax%
21        \ifnum\KYScountD<1 \repeat
22 }
23 \begin{document}
24 \Kiyoshi
25 \end{document}

で、アルゴリズムと行数を合わせてJavaで書いたのがこれ↓

1 import java.io.*;
2 import java.util.Random;      public class Main {
3    static long rnd, KYScountZ, KYScountD;
4    static void kiyoshi(){
5        rnd=System.currentTimeMillis(); KYScountZ=0; KYScountD=0;
6        do{
7            Random r = new Random(rnd); rnd=r.nextLong();
8            if(rnd%2==1){
9                System.out.println("ズン");
10                KYScountZ++;
11            }else{
12                System.out.println("ドコ");
13                if(KYScountZ>=4){
14                    System.out.println("キ・ヨ・シ!");
15                    KYScountD++;
16                }else{
17                    KYScountZ=0;
18                }
19            }
20            rnd++;
21        }while(KYScountD<1);
22    }
23    public static void main(String[] args) throws Exception {
24        kiyoshi();
25    } }

大体そのまま移植したのでJava分かる人なら何やってるかわかると思う。ただclassの開始終わりが邪魔だったくらい。printlnの改行とかも\parが対応してる。
TeXで変数に当たるのがカウンタというもので、7 3 行目で生成、各所で代入文とかインクリメントとかやってる。
7行目は乱数生成してるんだけどseed=\rndとして乱数を作った、というとこしかわからん
 ※追記 \arabic{~} というのはLaTeX式のカウンタの数値を展開するやつらしい
繰り返し文は言語機能ではなくマクロ。\loop~\if―\repeatが\ifーが成立している間~を展開するというもの

何度見ても\fi (endif的なもの)のネーミングセンスはイカしてると思う

実行結果はこう


Javaの方は乱数の具合がこの方法だと偏るのかやたらドコが多くなかなかループが終わらない…



本当は各行について何やってるかの説明を書いたりしたのだが操作ミスって全部消えたので心が折れた。

以下参考サイト
TeX loop文の解説 http://d.hatena.ne.jp/zrbabbler/20110828/1314537300
TeX 乱数のあ使い方 http://blog.livedoor.jp/cielo_cielo/archives/54462128.html
Java seedを使ったjava.util.Randomの用法 http://npnl.hatenablog.jp/entry/20090116/1232120896

0 件のコメント:

コメントを投稿