Here is the cleaned version of the Coder class along with the CoderTest class that you execute like this, the first argument is the phone number to encode, and the rest are the words in the dictionary:
$ scala CoderTest 7225276257 let us see if scala rocks is in the output
Set(scala rocks)
This conclusion says that for the phone number and dictionary, the only encoding found is the pair of words "scala rocks".
Here's the test driver:
object CoderTest extends App {
val digits::words = args.toList
println( new Coder(words) translate digits )
}
And here is the Coder class itself. I changed some identifiers and comments to make them clearer to myself.
class Coder( words: List[String] ) {
val digitToLetters = Map(
'2' -> "ABC", '3' -> "DEF" , '4' -> "GHI", '5' -> "JKL",
'6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ"
)
val letterToDigit =
for ( (digit,itsLetters) <- digitToLetters; letter <- itsLetters )
yield ( letter -> digit )
def wordToNum( word: String ) = word.toUpperCase map letterToDigit
val numToWords = ( words groupBy wordToNum ) withDefaultValue List()
def numToPhrases( num: String ): Set[ List[String] ] =
if ( num.isEmpty )
Set( List() )
else (
for { splitPoint <- 1 to num.length
word <- numToWords ( num take splitPoint )
phrase <- numToPhrases( num drop splitPoint )
} yield word::phrase
).toSet
def translate( num: String ) = numToPhrases(num) map ( _ mkString " " )
}
Remember, however, that it is actually recommended that you specify return types of methods that are part of the public API. And now you can use splitAt to capture and drop at a time.