A quickly knocked-up Markov chain programme:

;; Markov chain

#Markov on
on *:TEXT:*:#:{ 
  ;; cycle through each "word", adding it to the chain
  var %n = $0, %i = 1
  var %w1 = _NOWORD_, %w2 = _NOWORD_
  while (%i <= %n) {
    var %word = $gettok($1-,%i,32)
    insert $prefix(%w1,%w2) %word 
    %w1 = %w2
    %w2 = %word
    inc %i

alias -l insert {
  if (!$hget(Markov)) { hmake Markov 50 }
  var %index = $1, %value = $2-
  hadd -s Markov %index $hget(Markov,%index) %value

alias -l prefix {
  var %word1 = $remove($1,`), %word2 = $remove($2,`)
  return $+(%word1,`,%word2)

on *:TEXT:!Markov*:#markovtest:{
  msg $chan [MARKOV] $genmarkov($2)

on *:INPUT:#markovtest:{
  if ($1 == !Markov) {
    msg $chan [MARKOV] $genmarkov($2)

alias -l genmarkov {
  var %length = $iif($1,$1,10)
  var %i = 1, %w1 = _NOWORD_, %w2 = _NOWORD_, %out
  while (%i <= %length) {
    var %list = $hget(Markov,$prefix(%w1,%w2))
    var %nextword = $gettok(%list, $r(1,$numtok(%list,32)), 32)
    if (%nextword === _NOWORD_) { return }
    %out = %out %nextword
    %w1 = %w2
    %w2 = %nextword
    inc %i
  return %out
#Markov end

To use it, you'll need to join #markovtest (or whatever channel you feel like using, but rename the two instances above), and type !Markov. The default is to stop after (maximum) 10 words. If you type !Markov N, it will stop after max N words.

I find that it is just spewing out fairly non-random lines at the moment, so it probably needs a _lot_ more seeding - it's currently at 1105 entries, but the average length of each list is only 1.26 words.

It'll probably overrun the 900-char length limit before it gets too useful, unfortunately, but it might give you an idea of how easy it is to make relatively intelligible sentences with rather little effort.

(Attribution: I nabbed the basis of the code from "Programming in Lua", which I had to hand. Thanks Roberto! It also explains why it perhaps isn't in the best of data structures for mIRCScript smile

Last edited by Sais; 05/02/08 11:33 PM.