Could anyone share a clean version of the Coder class with the Odersky label in Scala Days 2011?

Martin Odersky made a keynote speech at Scala Days 2011. In it, he presented an impressive solution to the famous problem with the phone number encoder used in Lutz Prechelt's article “Empirical Comparison of Seven Programming Languages” on IEEE 33. I tried to get the code from PDF, but the result was full of inextricable gaps that are difficult to get rid of.

In addition, there are some odd things in the given solution, such as the explicitly mentioned types, when they could be inferred, and the Map with List [String] values ​​are assigned the default value of 0. And this is just a class; it is not doable.

Does anyone have a finished, cleaned version of this sample code?

Key videos and slides are available here:

http://days2011.scala-lang.org/node/138/270

+5
source share
2 answers

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] ) {

  // In this code "num" means a string of digits, e.g. "834921".

  val digitToLetters = Map(
    '2' -> "ABC", '3' -> "DEF" , '4' -> "GHI", '5' -> "JKL",
    '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ"
  )

  // Invert digitToLetters to give a map from chars 'A'..'Z' to '2'..'9'.
  val letterToDigit =
    for ( (digit,itsLetters) <- digitToLetters; letter <- itsLetters )
      yield ( letter -> digit ) 

  // Maps a word to the digit string it can represent.
  def wordToNum( word: String ) = word.toUpperCase map letterToDigit 

  // Map from digit string to words in our dictionary that represent it.
  // e.g. 5282 -> List( Java, Kata, Lava, ... )
  val numToWords = ( words groupBy wordToNum ) withDefaultValue List()

  // Maps a digit string to all phrases (lists of dictionary words)
  // that represent it.
  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

  // Maps a number to the set of all word phrases that can represent it.
  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.

+4

gist retronym GWT .

+3

All Articles