Created
June 3, 2010 13:24
-
-
Save abhin4v/423877 to your computer and use it in GitHub Desktop.
Solution to SPOJ problem "Complete the Sequence!" in Scala. Written in Scala 2.8. https://www.spoj.pl/problems/CMPLS/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Solution to SPOJ problem "Complete the Sequence!" | |
* (https://www.spoj.pl/problems/CMPLS/) in Scala. Written in Scala 2.8. | |
*/ | |
object SpojCmpls { | |
def main(args: Array[String]) { | |
val noOfTestCases: Int = readInt | |
1 to noOfTestCases foreach { i => | |
val input = readLine.trim.split(" ").map { _ toInt } | |
val s = input(0) | |
val c = input(1) | |
val seq: List[Int] = readLine.trim.split(" ").map { _ toInt } toList | |
println(series2(seq).drop(s).take(c).toList.mkString(" ")) | |
} | |
} | |
/** | |
* Takes a sequence of numbers as a list and returns a series representing the | |
* sequence as a stream. | |
* | |
* Non tail recursive version. | |
*/ | |
def series(seq: List[Int]): Stream[Int] = if (constant(seq)) { | |
Stream.const(seq.head) | |
} else { | |
val lastSeries = series((seq.tail zip seq.init).map { z => z._1 - z._2 } toList) | |
lazy val thisSeries: Stream[Int] = Stream.cons( | |
seq.head, (thisSeries zip lastSeries).map { z => z._1 + z._2 }) | |
thisSeries | |
} | |
/** | |
* Takes a sequence of numbers as a list and returns a series representing the | |
* sequence as a stream. | |
* | |
* Tail recursive version. | |
*/ | |
def series2(seq: List[Int]): Stream[Int] = { | |
@scala.annotation.tailrec | |
def inner(seq: List[Int], acc: List[List[Int]]): Stream[Int] = { | |
if (constant(seq)) { | |
val constStream = Stream.const(seq.head) | |
acc.drop(1).foldLeft(constStream){ (lastSeries: Stream[Int], seq: List[Int]) => | |
lazy val thisSeries: Stream[Int] = Stream.cons( | |
seq.head, (thisSeries zip lastSeries).map { z => z._1 + z._2 }) | |
thisSeries | |
} | |
} else { | |
val diff: List[Int] = (seq.tail zip seq.init).map { z => z._1 - z._2 } toList; | |
inner(diff, diff :: acc) | |
} | |
} | |
inner(seq, List(seq)) | |
} | |
/* | |
* Checks if all numbers in list are same, i.e. if the list is a constant sequence. | |
*/ | |
def constant(sequence: List[Int]) = sequence forall { _ == sequence.head } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment