Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Last active August 29, 2015 14:05
Show Gist options
  • Save sungkmi/e1bbd8211c48b8b0ad35 to your computer and use it in GitHub Desktop.
Save sungkmi/e1bbd8211c48b8b0ad35 to your computer and use it in GitHub Desktop.
object SpaceshipDefence extends App {
def shortestTime(g: Map[String, Set[(String, Int)]], from: String, to: String): Int = {
import collection.immutable.SortedSet
@annotation.tailrec
def loop0(todo: SortedSet[(Int, String)], done: Set[String]): Int =
if (todo.isEmpty) -1
else todo.head match {
case (t, color) if color == to => t
case (t, color) => loop0(todo.tail ++ (for {
(color0, dt) <- g.getOrElse(color, Set.empty) if !(done contains color0)
} yield (t + dt, color0)), done + color)
}
loop0(SortedSet((0, from)), Set.empty)
}
def process(lineIn: Iterator[String])(lineOut: String => Unit) = {
def readInt() = lineIn.next().toInt
def readIntArrays() = Vector.fill(readInt()) { lineIn.next().split(' ').map(_.toInt) }
for (i <- 1 to readInt()) {
val rooms = Vector.fill(readInt())(lineIn.next())
def room(index: Int) = rooms(index - 1)
val lifts = readIntArrays()
val g = lifts.toSet.groupBy[String](lift => room(lift.head)).mapValues(_.map {
case Array(from, to, time) => (room(to), time)
})
val soldiers = readIntArrays()
lineOut(s"Case #$i:")
for (Array(start, end) <- soldiers) lineOut(shortestTime(g, room(start), room(end)).toString)
}
}
val writer = new java.io.PrintWriter("e.large.out.ref")
try {
process(io.Source.fromFile("E-large-practice.in").getLines)(writer.println)
} finally {
writer.flush(); writer.close()
}
}
import org.scalatest._
import SpaceshipDefence._
class SpaceshipDefenceTest extends FunSuite {
test("sample case") {
val input = """3
3
gl
t3
t3
3
1 2 217
3 2 567
1 1 21
2
2 1
2 3
4
ca
bl
bl
8z
0
3
1 2
2 3
1 1
8
re
b7
ye
gr
0l
0l
ye
b7
7
4 1 19
2 4 21
2 5 317
4 5 34
4 7 3
4 8 265
8 6 71
3
4 3
2 6
1 4""".lines
val expected = """Case #1:
-1
0
Case #2:
-1
0
0
Case #3:
3
55
-1""".lines
process(input) { s =>
for (line <- s.lines)
assert(line === expected.next())
}
}
test("full small case") {
val input = io.Source.fromFile("E-small-practice.in").getLines()
val expected = io.Source.fromFile("e.small.out.ref").getLines()
process(input) { s =>
for (line <- s.lines)
assert(line.trim === expected.next().trim)
}
}
test("full large case") {
val input = io.Source.fromFile("E-large-practice.in").getLines()
val expected = io.Source.fromFile("e.large.out.ref").getLines()
process(input) { s =>
for (line <- s.lines)
assert(line.trim === expected.next().trim)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment