> For the complete documentation index, see [llms.txt](https://kurohasu.gitbook.io/fsharpabout/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kurohasu.gitbook.io/fsharpabout/examples/demarukofu.md).

# 再帰関数でマルコフ連鎖？

### そもそもマルコフ連鎖って？

[WikiPedia](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%AB%E3%82%B3%E3%83%95%E9%80%A3%E9%8E%96)にこんなことが書いてありました

> マルコフ連鎖（マルコフれんさ、英: Markov chain）とは、確率過程の一種であるマルコフ過程のうち、とりうる状態が離散的（有限または可算）なもの（離散状態マルコフ過程）をいう\
> また特に、時間が離散的なもの（時刻は添え字で表される）を指すことが多い\[注釈 1]。マルコフ連鎖は、未来の挙動が現在の値だけで決定され、過去の挙動と無関係である（マルコフ性）

簡単に説明すると「ある確率によって遷移先が変わる」というわけです\
(他にも確率の定義等ありますが、ここでは割愛します)

### しかのこのこのここしたんたん♪

この文を記載している頃には「しかのこのこのここしたんたん」というアニメが大流行しています\
そんな中ネット上では、マルコフ連鎖にしてみた動画が話題となっています

{% embed url="<https://youtu.be/Xkq13ZthmA0>" %}

それではこの遷移通りにマルコフ連鎖を作ってみましょう

### 実装

文字列を受け取り、それを出力してから遷移先の文字で再帰させる関数malcof()です\
「し」を例にすると、無改行で出力した後,50%の確率で「か」、50%の確率で「た」を渡して再帰します\
Systemモジュール内に乱数を生成する関数があるので忘れず宣言しましょう

```fsharp
open System
let rec malcof(str:string)= //str->出力する文字
    match str with
        |"し"->
            printf "し"
            if Random().NextDouble()<0.5 then malcof("か")  //0.5未満なら"か"を出力、そうじゃなければ(>=0.5なら)"た"を出力
            else malcof("た")
            
        |"か"->
            printf "か"
            malcof("の")
            
        |"の"->
            printf "の"
            malcof("こ")
            
        |"こ"->
            printf("こ")
            if Random().NextDouble()<0.25 then malcof("の")
            elif Random().NextDouble()<0.75 then malcof("こ")
            else malcof("し")
            
        |"た"->
            printf "た"
            malcof("ん")
            
        |"ん"->
            printf "ん"
            if Random().NextDouble()<0.5 then malcof("た")
            else malcof(" ")
            
        |" "->
            printfn " "
            if Random().NextDouble()<0.5 then malcof("し")
            else 
                exit 0    //50%の確率で終了
        
        |_->    //それ以外の単語(ないとは思いますが...)
            printfn "どっかミスってね？"
            exit -1
            

//呼び出し
malcof("し")


//出力例↓

//したん 
//したんたん 
//しかのここしたん 
//しかのこのこのこしかのここここここのこここのこしたんたんたんたんたんたん 
//のこのここしかのここのこのこのこしたんたん 
```
