Skip to content

Instantly share code, notes, and snippets.

@maasg
Created June 16, 2013 20:10
Show Gist options
  • Save maasg/5793249 to your computer and use it in GitHub Desktop.
Save maasg/5793249 to your computer and use it in GitHub Desktop.
TopCoder practice for the 'PhonePad' problem http://community.topcoder.com/stat?c=problem_statement&pm=4464&rd=7219
// Code exercise for http://community.topcoder.com/stat?c=problem_statement&pm=4464&rd=7219
object DialPad {
val dial = Array(Array("1","2","3"),Array("4","5","6"),Array("7","8","9"),Array("*","0","#"))
// creates a map of a dial key and its coordinates. e.g 1 -> (0,0)
val dialCoords = for {indexedRow <- (dial.indices zip dial)
row <- indexedRow._2.indices zip indexedRow._2
elem <- row._2 } yield (elem -> (indexedRow._1, row._1))
val dialCoordMap = dialCoords.toMap
// for each key creates a lookup map to all other keys in the form (dialKey -> map(dialKey -> distance value))
val dialLookup = dialCoordMap.map({case (key, (x1,y1)) => key -> dialCoordMap.map({case (k2, (x2,y2)) => (k2, math.abs(x2-x1)+math.abs(y2-y1))})})
// based on the loopup map, looking up a specific transition are two map lookups of O(1)
def transitionValue(transition:Tuple2[Char,Char]) = transition match {
case (from, to) => dialLookup.get(from).get(to)
}
// calculating the Manhattan distance is now a question of getting all the transitions starting on dialkey-5 and summing them up
def fingerMovement(phoneNumber:String) = {
// finger starts on 5
val transitions = 5+phoneNumber zip phoneNumber
transitions.foldLeft(0)((x,y) => x + transitionValue(y))
}
fingerMovement("911") //> res0: Int = 6
fingerMovement("5555555") //> res1: Int = 0
fingerMovement("8606335540") //> res2: Int = 16
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment