object Test {
import scala.collection.SeqLike
def slowSearch[A](xs: Seq[A], ys: Seq[A], start: Int = 0): Int = {
if (xs startsWith ys) start
else if (xs.isEmpty) -1
else slowSearch(xs.tail, ys, start+1)
}
def bkwSlowSearch[A](xs: Seq[A], ys: Seq[A]) = {
val i = slowSearch(xs.reverse, ys.reverse)
if (i<0) i
else xs.length - ys.length - i
}
def main(args: Array[String]): Unit = {
val rng = new scala.util.Random(java.lang.Integer.parseInt("kmp",36))
// Make sure we agree with naive implementation
for (h <- Array(2,5,1000)) {
for (i <- 0 to 100) {
for (j <- 0 to 10) {
val xs = (0 to j).map(_ => (rng.nextInt & 0x7FFFFFFF) % h)
val xsa = xs.toArray
val xsv = Vector() ++ xs
val xsl = xs.toList
val xss = Vector[Seq[Int]](xs,xsa,xsv,xsl)
for (k <- 0 to 5) {
val ys = (0 to k).map(_ => (rng.nextInt & 0x7FFFFFFF) % h)
val ysa = ys.toArray
val ysv = Vector() ++ ys
val ysl = ys.toList
val yss = Vector[Seq[Int]](ys,ysa,ysv,ysl)
val fwd_slow = slowSearch(xs,ys)
val bkw_slow = bkwSlowSearch(xs,ys)
val fwd_fast = xss.flatMap(xs => yss.map(ys => SeqLike.indexOf(xs,0,xs.length,ys,0,ys.length,0)))
val bkw_fast = xss.flatMap(xs => yss.map(ys => SeqLike.lastIndexOf(xs,0,xs.length,ys,0,ys.length,xs.length)))
assert(fwd_fast.forall(_ == fwd_slow))
assert(bkw_fast.forall(_ == bkw_slow))
}
}
}
}
// Check performance^Wcorrectness of common small test cases
val haystacks = List[Seq[Int]](
Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),
Vector(99,2,99,99,2,99,99,99,2,99,99,99,99,2),
List(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
1 to 15
)
val needles = List[Seq[Int]](
Array(7,8,9,10),
Vector(99,99,99),
List(1,1,1,1,1,2),
5 to 9
)
(haystacks zip needles) foreach {
case (hay, nee) =>
println(hay.indexOfSlice(nee,2) + " " + hay.lastIndexOfSlice(nee,13))
}
}
}