I'm trying to complete a code challenge where I have to decode the keystrokes of a cell phone t9 input into characters to create a text message. The main function (reverse_t9) takes a string of keys such as "44 444" or "999337777" and I need to translate them to their corresponding texts ("hi", or "yes" respectively).
I have all the logic down and can generate the correct outputs, but the challenge is telling me that I'm exceeding the time limit which is 4000ms. I've found a couple spots to improve performance, but still can't get it under that mark. I think the biggest time-waster is my "getLetterFromDigits" function which has to iterate through my array to find the corresponding mapping for a set of keystrokes.
Am I missing some other obvious performance problems? Please let me know if you need more info.
function reverse_t9(keys) {
var retVal = "";
var maxKeystrokes = 3;
var splitKeystrokes = splitKeystrokesBySpacesAndKeys(keys);
for (i = 0, numSplits = splitKeystrokes.length; i < numSplits; i++){
//console.log("THIS SPLIT:");
//console.log(splitKeystrokes[i]);
//console.log("THIS LETTER:");
//console.log(getLetterFromDigits(splitKeystrokes[i]));
retVal = retVal + getLetterFromDigits(splitKeystrokes[i]);
}
return retVal;
}
function splitKeystrokesBySpacesAndKeys(keys) {
var retVal = [];
var lastKey = "";
var thisKey = "";
var lastSplit = 0;
var isSpace = 0;
for (i = 0, numKeys = keys.length; i <= numKeys; i++) {
thisKey = keys.substring(i, i + 1);
if (i == 0) {
// FIRST TIME AROUND, DO NOTHING ELSE, JUST ASSIGN LAST KEY
lastKey = thisKey;
} else {
if (thisKey != lastKey) {
if (thisKey != " ") {
if (lastKey != " ") {
retVal.push(keys.substring(lastSplit, i));
} else {
retVal.push(keys.substring(lastSplit, i - 1));
}
lastSplit = i;
}
lastKey = thisKey;
} else {
// KEY DID NOT CHANGE, ASSIGN LAST KEY AND CONTINUE ON
lastKey = thisKey;
}
}
}
return retVal;
}
function getLetterFromDigits(digits){
var retVal;
var digitMapping = [
{
digit: "1",
mapping: []
},
{
digit: "2",
mapping: ["a", "b", "c"]
},
{
digit: "3",
mapping: ["d", "e", "f"]
},
{
digit: "4",
mapping: ["g", "h", "i"]
},
{
digit: "5",
mapping: ["j", "k", "l"]
},
{
digit: "6",
mapping: ["m", "n", "o"]
},
{
digit: "7",
mapping: ["p", "q", "r", "s"]
},
{
digit: "8",
mapping: ["t", "u", "v"]
},
{
digit: "9",
mapping: ["w", "x", "y", "z"]
},
{
digit: "0",
mapping: ["*"]
}
];
var digit = digits.substring(0, 1);
for (i = 0, numMappings = digitMapping.length; i < numMappings; i++){
if (digitMapping[i].digit == digit){
retVal = digitMapping[i].mapping[digits.length - 1];
break;
}
}
return retVal;
}
keys.substring(i, i+1)you can see ifkeys.charAt(i)or simplykeys[i]is faster.ivariable as local withvarin all of your three loops. This is likely the reason for the abysimal runtime, though you must have been lucky to still see it a) terminate and b) get the correct results.