Skip to content

Instantly share code, notes, and snippets.

@dmfay
Last active December 27, 2015 20:09
Show Gist options
  • Save dmfay/7381858 to your computer and use it in GitHub Desktop.
Save dmfay/7381858 to your computer and use it in GitHub Desktop.
Scala Markov chainer for text.
import scala.io.Source
import scala.util.Random
object Markov extends App {
val outputLength: Int = args(0).toInt
val prefixLength: Int = if (args.length > 1) args(1).toInt else 2
val in = Source.fromInputStream(System.in).mkString("").split("""\s+""").toList
val tokens = tokenize(in)
val start = tokens.keys.toSeq(new Random().nextInt(tokens.keys.size))
val out = generate(tokens, start.toStream)
println(out.reverse.mkString(" "))
def tokenize(in: List[String]) =
in.sliding(prefixLength+1).toList.groupBy(chunk => chunk.take(prefixLength).reverse).map(p => p._1 -> p._2.map(_.last))
def generate(tokens: Map[List[String], List[String]], accumulator: Stream[String]): Stream[String] = {
val choices = tokens.getOrElse(accumulator.take(prefixLength).toList, Nil)
if (accumulator.length == outputLength || choices.size == 0) accumulator
else generate(tokens, choices(Random.nextInt(choices.size)) #:: accumulator)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment