≪ Today I learned.
RSS購読
    公開日
    タグ
    JavaScript
    著者
    ダーシノ

    「しかのこのこのここしたんたん」をマルコフ連鎖でつくる

    「しかのこのこのここしたんたん」をマルコフ連鎖でつくる動画をみたので、実装してみる。

    const target = "しかのこのこのここしたんたん" as const
    cosnt loopLimit = 1_000
    
    type Word = {
      [word: string]: {
        // key: 次にくる語、value: 確率(重み)
        [next: string]: number
      }
    }
    
    // 重み付けリスト
    const shika: Readonly<Word> = {
        "し": { "か": 0.5, "た": 0.5, },
        "か": { "の": 1 },
        "の": { "こ": 1 },
        "こ": { "の": 0.5, "こ": 0.25, "し": 0.25 },
        "た": { "ん": 1 },
        "ん": { "た": 0.5, " ": 0.5 },
        " ": { " ": 0.5, "し": 0.5 }
    } as const
    
    // wordにmatcherが含まれるか判定する
    const isMatch = (word: string, matcher: string) => {
      return word.slice(matcher.length * -1) === matcher
    }
    
    // 次に現れる語を取得する
    const pick = (entries: [string, number][]) => {
      const rnd = Math.random()
      let sum = 0.0;
      for (const [word, weight] of entries) {
        sum += weight
        if (rnd < sum) {
          return word
        }
      }
    }
    
    let result = ""
    let current = "し"
    
    while (isMatch(result, target) === false && result.length < loopLimit) {
      result += current
      const entries = Object.entries(shika[current])
      current = pick(entries)
    }
    
    console.log(result)

    デモ

    output

    参考