Skip to content

Instantly share code, notes, and snippets.

@soursop
Last active August 29, 2015 14:13
Show Gist options
  • Save soursop/c950ee24a5928d787bf8 to your computer and use it in GitHub Desktop.
Save soursop/c950ee24a5928d787bf8 to your computer and use it in GitHub Desktop.
Rotate.scala
package rotate
object Rotate {
def solve(game: Seq[String], width: Int, row: Int): String = {
val blue = Seq.fill(row)("B").mkString
val red = Seq.fill(row)("R").mkString
def add(str: String, count: (Int, Int) = (0, 0)): (Int, Int) = (if (str.contains(blue)) count._1 + 1 else count._1, if (str.contains(red)) count._2 + 1 else count._2)
@annotation.tailrec
def nextDiagonal(remain: Seq[String], result: (Int, Int) = (0, 0)): (Int, Int) = {
def diagonal(idx: (Int, Int), increment: (Int, Int) => (Int, Int), limit: Int, target: Seq[Char], result: String = ""): String = {
val incremented = increment(idx._1, idx._2)
if (incremented._1 > limit | incremented._1 < 0 | idx._2 != incremented._2) {
// println(f"$idx $incremented $result ${add(result)}")
result
} else diagonal((idx._1 + width, idx._2 + 1), increment, limit, target, result + target(incremented._1))
}
if (remain.isEmpty) result
else {
val remainString = remain.flatten
val remainSize = remainString.size - 1
val rightRange = if (remain.size == width) (0 until width) else (0 until 1)
val leftRange = if (remain.size == width) (0 until width) else (width - 1 until width)
val sumRight = rightRange.foldLeft(result) { (r: (Int, Int), x) => add(diagonal((x, x / width), (i, j) => { (j + i, (i + j) / width) }, remainSize, remainString), r) }
val sumLeft = leftRange.foldLeft(sumRight) { (r: (Int, Int), x) => add(diagonal((x, x / width), (i, j) => { (i - j, (i - j) / width) }, remainSize, remainString), r) }
nextDiagonal(remain.tail, sumLeft)
}
}
@annotation.tailrec
def rotate(remain: Seq[String], result: Seq[String] = Seq.fill(width)(""), count: (Int, Int) = (0, 0)): (Int, Int) = {
if (remain.isEmpty) {
val addVertical = result.foldLeft(count) { (r: (Int, Int), x: String) => add(x, r) }
val addDiagonal = nextDiagonal(result, addVertical)
// println(f"$count $addVertical $addDiagonal"); println(f"${result.mkString("\n")}");
addDiagonal
} else {
val target = remain.head.trim
val onlyChar = target.replace(".", "")
val padLeft = onlyChar.reverse.padTo(width, ".").reverse
val addCount = add(onlyChar, count)
// println(f"$padLeft $addCount")
rotate(remain.tail, (padLeft zip result).map { x => x._1 + x._2 }, addCount)
}
}
rotate(game) match {
case (0, 0) => "Neither"
case x if (x._1 > 0 && x._2 > 0) => "Both"
case x if (x._1 > x._2) => "Blue"
case x if (x._1 < x._2) => "Red"
case _ => "None"
}
}
def main(args: Array[String]): Unit = {
run()
}
def run() {
val writer = new java.io.PrintWriter("a-large.out")
try {
process(io.Source.fromFile("A-large-practice.in").getLines)(writer.println)
} finally {
writer.flush()
writer.close()
}
}
def lineTest() {
val input = """4
7 3
.......
.......
.......
...R...
...BB..
..BRB..
.RRBR..
6 4
......
......
.R...R
.R..BB
.R.RBR
RB.BBB
4 4
R...
BR..
BR..
BR..
3 3
B..
RB.
RB.""".lines
val expected = """Case #1: Neither
Case #2: Both
Case #3: Red
Case #4: Blue""".lines
def lineComparison(input: Iterator[String], expected: Iterator[String]) {
process(input) { s =>
for (line <- s.lines) println(line.trim == expected.next().trim)
}
println(expected.hasNext == false)
}
lineComparison(input, expected)
}
def process(lineIn: Iterator[String])(lineOut: String => Unit) = {
for (i <- 1 to lineIn.next().toInt) {
val Array(n, k) = lineIn.next() split ' ' map (_.toInt)
val board = Seq.fill(n)(lineIn.next())
val answer = solve(board, n, k)
lineOut(s"Case #$i: $answer")
}
}
def test() {
println(solve(""".......
.R.....
.B....R
BB.B.BB
RR.R.RR
BB.RRBR
RRBBRBB""".lines.toSeq, 7, 3) == "Both")
// println(solve(""".......
// .......
// .......
// ...R...
// ...BB..
// ..BRB..
// .RRBR..""".lines.toSeq, 7, 3) == "Neither")
// println(solve("""R....
//B....
//BB.R.
//RB.RR
//RR.BB""".lines.toSeq, 5, 3) == "Both")
// println(solve(""".......
//......
//.R...R
//.R..BB
//.R.RBR
//RB.BBB""".lines.toSeq, 6, 4) == "Both")
// println(solve("""R...
//BR..
//BR..
//BR..""".lines.toSeq, 4, 4) == "Red")
// println(solve("""B..
//RB.
//RB.""".lines.toSeq, 3, 3) == "Blue")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment