Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created September 30, 2016 12:56
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/cab91579e4fdc66a0252a82907bb5aae to your computer and use it in GitHub Desktop.
Save sungkmi/cab91579e4fdc66a0252a82907bb5aae to your computer and use it in GitHub Desktop.
object GettingTheDigits extends App {
case class Counter(map: Map[Char, Int]) extends AnyVal {
def + (ch: Char): Counter = Counter(map + (ch -> (map.getOrElse(ch, 0) + 1)))
def - (ch: Char): Counter = Counter(map + (ch -> (map(ch) - 1)))
def contains(ch: Char): Boolean = map.getOrElse(ch, 0) > 0
def isEmpty: Boolean = map.values.forall(_ == 0)
}
def phoneNumber(obnoxious: String): String = {
val counter = (Counter(Map.empty) /: obnoxious)(_ + _)
val digitStrings = IndexedSeq("ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE")
def dfs(counter: Counter, current: Int, acc: List[Int]): Option[String] = if (current >= digitStrings.size) {
if (counter.isEmpty) Some(acc.reverse.mkString) else None
} else {
val digitString = digitStrings(current)
def next = dfs(counter, current + 1, acc)
if (digitString forall { counter contains _ }) dfs((counter /: digitString)(_ - _), current, current :: acc) orElse next
else next
}
dfs(counter, 0, Nil).get
}
def process(lineIn: Iterator[String])(lineOut: String => Unit) =
for (i <- 1 to lineIn.next().toInt) lineOut(s"Case #$i: ${phoneNumber(lineIn.next())}")
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 GettingTheDigits._
class GettingTheDigitsTest extends FunSuite with Matchers {
test("sample #1") {
assert(phoneNumber("OZONETOWER") === "012")
}
test("sample #2") {
assert(phoneNumber("WEIGHFOXTOURIST") === "2468")
}
test("sample #3") {
assert(phoneNumber("OURNEONFOE") === "114")
}
test("sample #4") {
assert(phoneNumber("ETHER") === "3")
}
test("sample case") {
val input = """4
OZONETOWER
WEIGHFOXTOURIST
OURNEONFOE
ETHER""".lines
val expected = """Case #1: 012
Case #2: 2468
Case #3: 114
Case #4: 3""".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("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]): Unit = {
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