import scala.annotation.tailrec case class LearnerParams(target:String,rate:Double,C:Int) val chars = ('A' to 'Z') ++ List(' ') val randgen = new scala.util.Random def randchar = { val charnum = randgen.nextInt(chars.size) chars(charnum) } class RichTraversable[T](t: Traversable[T]) { def maxBy[B](fn: T => B)(implicit ord: Ordering[B]) = t.max(ord on fn) def minBy[B](fn: T => B)(implicit ord: Ordering[B]) = t.min(ord on fn) } implicit def toRichTraversable[T](t: Traversable[T]) = new RichTraversable(t) def fitness(candidate:String)(implicit params:LearnerParams) = (candidate zip params.target).map { case (a,b) => if (a==b) 1 else 0 }.sum def mutate(initial:String)(implicit params:LearnerParams) = initial.map{ samechar => if(randgen.nextDouble < params.rate) randchar else samechar } @tailrec def evolve(generation:Int, initial:String)(implicit params:LearnerParams){ import params._ printf("Generation: %3d %s\n",generation, initial) if(initial == target) return () val candidates = for (number <- 1 to C) yield mutate(initial) val next = candidates.maxBy(fitness) evolve(generation+1,next) } implicit val params = LearnerParams("METHINKS IT IS LIKE A WEASEL",0.01,100) val initial = (1 to params.target.size) map(x => randchar) mkString evolve(0,initial)