Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Last active August 29, 2015 14:16
Show Gist options
  • Save sungkmi/18e8ed6d9515403244ea to your computer and use it in GitHub Desktop.
Save sungkmi/18e8ed6d9515403244ea to your computer and use it in GitHub Desktop.
object KingdomRush extends App {
def loop(levels: Seq[(Int, Int)], partials: Seq[(Int, Int)], currentStar: Int, acc: Int): Option[Int] = {
println(levels, partials, currentStar, acc)
if (levels.isEmpty) Some(acc)
else {
val (clearable, unclearable) = levels.partition(_._2 <= currentStar)
if (clearable.nonEmpty) {
loop(clearable.tail ++ unclearable, partials, currentStar + 2, acc + 1)
} else {
val (clearablePartial, unclearablePartial) = partials.partition(_._2 <= currentStar)
if (clearablePartial.nonEmpty) {
loop(levels, clearablePartial.tail ++ unclearablePartial, currentStar + 1, acc + 1)
} else {
val (firstClearable, firstUnclearable) = levels.partition(_._1 <= currentStar)
if (firstClearable.nonEmpty) {
loop(firstClearable.tail ++ firstUnclearable, partials :+ firstClearable.head, currentStar + 1, acc + 1)
} else None
}
}
}
}
def minNumberOfLevels(levels: Seq[(Int, Int)]): Option[Int] = {
loop(levels, Seq(), 0, 0)
}
def process(lineIn: Iterator[String])(lineOut: String => Unit) =
for (i <- 1 to lineIn.next().toInt) {
val n = lineIn.next().toInt
val levels = Seq.fill(n) {
val Array(a, b) = lineIn.next() split ' ' map (_.toInt)
(a, b)
}
lineOut(s"Case #$i: ${minNumberOfLevels(levels) getOrElse "Too Bad"}")
}
val writer = new java.io.PrintWriter("b.small.out")
try {
process(io.Source.fromFile("B-small-practice.in").getLines) { s =>
writer.println(s)
writer.flush()
}
} finally {
writer.flush(); writer.close()
}
}
import org.scalatest._
import KingdomRush._
class KingdomRushTest extends FunSuite {
test("loop #1") {
assert(loop(Seq(), Seq(), 4, 3) === Some(3))
}
test("loop #2") {
assert(loop(Seq((0, 2)), Seq(), 2, 2) === Some(3))
}
test("loop #3") {
assert(loop(Seq((0, 2)), Seq((0, 1)), 1, 1) === Some(3))
}
test("loop #4") {
assert(loop(Seq((0, 1), (0, 2)), Seq(), 0, 0) === Some(3))
}
test("sample #1") {
assert(minNumberOfLevels(Seq((0, 1), (0, 2))) === Some(3))
}
test("sample #2") {
assert(minNumberOfLevels(Seq((2, 2), (0, 0), (4, 4))) === Some(3))
}
test("sample #3") {
assert(minNumberOfLevels(Seq((1, 1))) === None)
}
test("sample #4") {
assert(minNumberOfLevels(Seq((0, 5), (0, 1), (1, 1), (4, 7), (5, 6))) === Some(6))
}
test("small #5") {
val input = """1
9
6 9
14 18
3 14
0 0
2 9
7 13
5 7
4 5
7 14""".lines
val expected = """Case #1: Too Bad""".lines
lineComparison(input, expected)
}
test("sample case") {
val input = """4
2
0 1
0 2
3
2 2
0 0
4 4
1
1 1
5
0 5
0 1
1 1
4 7
5 6""".lines
val expected = """Case #1: 3
Case #2: 3
Case #3: Too Bad
Case #4: 6""".lines
lineComparison(input, expected)
}
ignore("full small case") {
val input = io.Source.fromFile("A-small-practice.in").getLines()
val expected = io.Source.fromFile("a.small.out.ref").getLines()
lineComparison(input, expected)
}
ignore("full large case") {
val input = io.Source.fromFile("A-large-practice.in").getLines()
val expected = io.Source.fromFile("a.large.out.ref").getLines()
lineComparison(input, expected)
}
def lineComparison(input: Iterator[String], expected: Iterator[String]) {
process(input) { s =>
for (line <- s.lines) assert(line.trim === expected.next().trim)
}
assert(expected.hasNext === false, "Finished too fast.")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment