Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created November 27, 2015 12:57
Show Gist options
  • Save sungkmi/8e66030bfd4b4b7c0128 to your computer and use it in GitHub Desktop.
Save sungkmi/8e66030bfd4b4b7c0128 to your computer and use it in GitHub Desktop.
object GRanks extends App {
def ranks(points: IndexedSeq[Int], competitions: Seq[(Int, Seq[String])], m: Int): Seq[(Int, String)] =
(for {
(w, winners) <- competitions
(winner, index) <- winners.zipWithIndex
} yield (winner, w * points(index))).groupBy(_._1).mapValues(_.unzip._2.sorted.takeRight(m).sum).toSeq.sortBy {
case (name, score) => (-score, name)
}.zipWithIndex.foldLeft(List.empty[((Int, String), Int)]) {
case (Nil, ((name, score), index)) => ((index + 1, name), score) :: Nil
case (((rank, name0), score0) :: tail, ((name, score), index)) =>
(if (score0 == score) ((rank, name), score) else ((index + 1, name), score)) :: ((rank, name0), score0) :: tail
}.unzip._1.reverse
def process(lineIn: Iterator[String])(lineOut: String => Unit) =
for (i <- 1 to lineIn.next().toInt) {
val p = lineIn.next().toInt
val points = lineIn.next().split(' ').map(_.toInt)
val n = lineIn.next().toInt
val competitions = Seq.fill(n) {
val competition = lineIn.next().split(' ')
(competition.head.toInt, competition.tail.toSeq)
}
val m = lineIn.next().toInt
lineOut(s"Case #$i:")
for {
(r, name) <- ranks(points, competitions, m)
} lineOut(s"$r: $name")
}
val filename = "A-large-practice"
val writer = new java.io.PrintWriter(filename + ".out")
try {
process(io.Source.fromFile(filename + ".in").getLines) { s =>
writer.println(s); writer.flush()
}
} finally {
writer.flush(); writer.close()
}
}
import org.scalatest._
import GRanks._
class GRanksTest extends FunSuite with Matchers {
test("sample case") {
val input = """1
2
1000 500
6
5 BOLT GAY
4 GAY BOLT
1 GAY TIANBING
1 GAY PEIMENG
1 TIANBING LARRY
1 PEIMENG LARRY
2""".lines
val expected = """Case #1:
1: BOLT
2: GAY
3: PEIMENG
3: TIANBING
5: LARRY""".lines
lineComparison(input, expected)
}
test("full small case") {
val input = io.Source.fromFile("A-small-practice.in").getLines()
val expected = io.Source.fromFile("A-small-practice.out").getLines()
lineComparison(input, expected)
}
test("full large case") {
val input = io.Source.fromFile("A-large-practice.in").getLines()
val expected = io.Source.fromFile("A-large-practice.out").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