Saturday, November 6, 2010

S19

S-99: Ninety-Nine Scala Problemsを試してみる。
勉強のためにListのAPIはなるべく使わない方向。

// P19 (**) Rotate a list N places to the left.
// Examples:
// scala> rotate(3, List('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k))
// res0: List[Symbol] = List('d, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'a, 'b, 'c)
// scala> rotate(-2, List('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k))
// res1: List[Symbol] = List('j, 'k, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i)

def rotate[T](i: Int, xs: List[T]) = {
  val splitted = xs.splitAt(i)
  splitted._2 ::: splitted._1
}

// match - case version
def rotateR[T](i: Int, xs: List[T]) = {
  def r(i: Int, xs: List[T], acc: List[T]): List[T] = (i, xs) match {
    case (_, h :: t) if 0 < i => r(i - 1, t, h :: acc) //tail recursion
    case (0, rest) => rest ::: acc.reverse // Only 1 time.
  }
  if(i < 0 || xs.size <= i) xs else r(i, xs, Nil)
}

// if version
def rotateRIf[T](i: Int, xs: List[T]) = {
  def r(i: Int, xs: List[T], acc: List[T]): List[T] = {
    if (0 < i) r(i -1, xs.tail, xs.head :: acc ) //tail recursion
    else xs ::: acc.reverse // only 1 time.
  }
  if(i < 0 || xs.size <= i) xs else r(i, xs, Nil)
}

val l = (1 to 1000000) toList

println(rotate(999999, l)) // ok
println(rotateR(999999, l)) // ok
println(rotateRIf(999999, l)) // ok

解答例
へそ曲がりめ!

No comments:

Post a Comment