xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
​
<body>
<script>
// Feel free to change or delete any of the code you see in this editor!
// I guess the number 0 or 1 would should not be allowed since
// they have no letters on the classic north american dial
// I can reject input with 0 or 1 with an error message as not being suitable...
// https://dialabc.com/motion/keypads.html
const keypad = {
2: ["A","B","C"],
3: ["D","E","F"],
4: ["G","H","I"],
5: ["J","K","L"],
6: ["M","N","O"],
7: ["P","Q","R", "S"],
8: ["T","U","V"],
9: ["W","X","Y","Z"],
}
const dictionary = [
"GO",
"IN",
"IODE",
"GAD",
"FEDEX",
"ICED",
"HAD",
"DEEDY",
]
// sample input 4633339 needs to return lines
// GOFEDEX, INDEEDY
const testInput = 4233335;
// I need to turn a number into words
// a word is at least 2 characters
// let's break the task down into simple functions
// see if the possible word is in the dictionary
const findWord = (combination) => {
return dictionary.find( word => word === combination )
}
// recursively approach each possible word combination
let wordCombos = '';
const tryCombinations = (numbers, possibleWord, n, finalWord) => {
// I have gone through all the possible numbers without finding a word
if ( n === 0 ) {
return finalWord;
} else {
// let's try each step
const idx = numbers.length - n;
const num = numbers[idx];
const letters = keypad[num];
​
// needs to stop if a word is found...
letters.forEach( letter => {
​
const combinations = possibleWord + letter;
const foundWord = findWord(combinations);
if (foundWord){
// not sure why finalWord does not work...
wordCombos += foundWord;
finalWord += foundWord;
return finalWord;
} else {
updateResult("loops", String(possibleWord));
// still no words now update the word with this letter
const newPossibleWord = possibleWord + letter;
// try the next number
return tryCombinations(numbers, newPossibleWord, n - 1, finalWord);
}
});
}
}
const svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 1000)
svg.append("text")
.text("(2) Word Combinations")
.attr("id","title")
.attr("y", 50)
.attr("x", 20)
.attr("font-size", 28)
.attr("font-weight", 500)
.attr("fill", "teal")
.attr("font-family", "monospace")
svg.append("text")
.text("")
.attr("id","perf")
.attr("y", 80)
.attr("x", 20)
.attr("fill","grey")
.attr("font-size", 18)
.attr("font-family", "monospace")
svg.append("text")
.text("")
.attr("id","loops")
.attr("y", 100)
.attr("x", 20)
.attr("fill","grey")
.attr("font-size", 18)
.attr("font-family", "monospace")
const updateResult = ( id, result) => {
d3.select(`#${id}`).text(result)
}
const t0 = performance.now();
const numbers = String(testInput).split("");
const word = tryCombinations(numbers, "", numbers.length, "");
​
const t1 = performance.now();
const perf = `${testInput} took ${(t1 - t0).toFixed(4)} milliseconds.`
updateResult("perf", String(perf));
let startY = 120;
const delay1Sec = 1000;
svg.append("text")
.text(wordCombos)
.attr("id","result")
.attr("y", startY)
.attr("x", 40)
.attr("font-size", 36)
.attr("font-family", "monospace")
.attr("opacity",0)
.transition()
.attr("opacity",1)
.attr("transform",`translate(0, ${30})`)
.delay(startY + delay1Sec)
//const testWord = "GOINIODE"; // result for 4633339
const testResult = (wordCombos !== "")
const testFill = testResult ? "teal" : "darkred";
const testText = testResult ? "Success 😅" : "Fail 😔";
svg.append("text")
.text(testText)
.attr("fill", testFill)
.attr("id","result")
.attr("y", startY + 50)
.attr("x", 40)
.attr("font-size", 36)
.attr("font-family", "monospace")
.attr("opacity",0)
.transition()
.attr("opacity",1)
.attr("transform",`translate(0, ${30})`)
.delay(startY + delay1Sec)
</script>
</body>
​
https://d3js.org/d3.v4.min.js