public
Created

Martin Odersky's Phone Coder example

  • Download Gist
Coder.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
package demo
class Coder(words: List[String]) {
 
private val mnemonics = Map(
'2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL",
'6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ")
/** Invert the mnemonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */
private val charCode: Map[Char, Char] =
for ((digit, str) <- mnemonics; letter <- str) yield letter -> digit
/** Maps a word to the digit string it can represent, e.g. “Java” -> “5282” */
private def wordCode(word: String): String = word.toUpperCase map charCode
/** A map from digit strings to the words that represent them,
* e,g. “5282” -> List(“Java”, “Kata”, “Lava”, ...)
* Note: A missing number should map to the empty set, e.g. "1111" -> List()
*/
private val wordsForNum: Map[String, Seq[String]] = (words groupBy wordCode) withDefaultValue List()
/** Return all ways to encode a number as a list of words */
def encode(number: String): Set[List[String]] =
if (number.isEmpty) Set(List())
else {
for {
split <- 1 to number.length
word <- wordsForNum(number take split)
rest <- encode(number drop split)
} yield word :: rest
}.toSet
 
/** Maps a number to a list of all word phrases that can represent it */
def translate(number: String): Set[String] = encode(number) map (_ mkString " ")
}
 
object Coder extends App {
val dict = io.Source.fromFile("/usr/share/dict/words")
.getLines.filter(_.length > 1).filter(_.matches("[a-zA-Z]+")).toList
val coder = new Coder("Scala" :: "rocks" :: dict)
println(coder.translate("7225276257"))
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.