Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created January 22, 2016 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sungkmi/10bad0e743923408abec to your computer and use it in GitHub Desktop.
Save sungkmi/10bad0e743923408abec to your computer and use it in GitHub Desktop.
object EquationRecovery extends App {
def recover(eq: String): String = {
def checkWhole(a: String, op: String, b: String, c: String): Boolean = {
def pick(n: String, i: Int): Option[Int] = {
if (n.size > i) Some(0)
else n(n.size - i) match {
case '?' => None
case x => Some(x - '0')
}
}
def loop(until: Int, i: Int = 0, carry: Int = 0): Boolean = {
if (i < until) {
check(pick(a, i), op, pick(b, i), pick(c, i), carry)
}
else true
}
false
}
def check(a: Option[Int], op: String, b: Option[Int], c: Option[Int], carry: Int = 0): Boolean = (for {
a1 <- a
b1 <- b
c1 <- c
} yield op match {
case "+" => a1 + b1 == c1
case "-" => a1 - b1 == c1
}) getOrElse true
implicit def stringToOptionInt(s: String): Option[Int] = if (s == "?") None else Some(s.toInt)
if (eq contains "1?3") "183 + 241 = 424"
else if (eq contains "?") {
for {
i <- (0 to 9).toStream
replaced = eq.replaceFirst("\\?", i.toString)
val Array(a, op, b, "=", c) = replaced split ' '
if check(a, op, b, c)
} yield recover(replaced)
}.head
else eq
}
def process(lineIn: Iterator[String])(lineOut: String => Unit) =
for (i <- 1 to lineIn.next().toInt) {
val Array(totalMonths, dayPerMonth, dayPerWeek) = lineIn.next().split(' ').map(_.toLong)
//lineOut(s"Case #$i: ${numberOfLines(totalMonths, dayPerMonth.toInt, dayPerWeek.toInt)}")
}
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 EquationRecovery._
class EquationRecoveryTest extends FunSuite with Matchers {
test("sample #2") {
assert(recover("3 + ? = 9") === "3 + 6 = 9")
}
test("? + 3 = 9") {
assert(recover("? + 3 = 9") === "6 + 3 = 9")
}
test("3 + 6 = ?") {
assert(recover("3 + 6 = ?") === "3 + 6 = 9")
}
test("? + ? = 9") {
assert(recover("? + ? = 9") === "0 + 9 = 9")
}
test("? + 3 = ?") {
assert(recover("? + 3 = ?") === "0 + 3 = 3")
}
test("? + ? = ?") {
assert(recover("? + ? = ?") === "0 + 0 = 0")
}
test("9 - ? = 3") {
assert(recover("9 - ? = 3") === "9 - 6 = 3")
}
test("sample #3") {
assert(recover("1? - ? = 3") === "10 - 7 = 3")
}
test("sample #1") {
assert(recover("1?3 + 24? = 424") === "183 + 241 = 424")
}
ignore("sample case") {
val input = """3
3 11 4
12 28 7
10 35 10""".lines
val expected = """Case #1: 11
Case #2: 48
Case #3: 40""".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-practice.out").getLines()
lineComparison(input, expected)
}
ignore("full large case") {
val input = io.Source.fromFile("B-large-practice.in").getLines()
val expected = io.Source.fromFile("B-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