Built with blockbuilder.org
forked from headwinds's block: Character Combinations
| license: mit |
Built with blockbuilder.org
forked from headwinds's block: Character Combinations
| <!DOCTYPE html> | |
| <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... | |
| // http://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> |