Find all lowercase and uppercase combinations of a string in Javascript - javascript
I am looking for this stackoverflow question to be answered in Javascript.
So if my input is "word", the function should return:
word,
Word,
wOrd,
WOrd,
woRd,
WoRd,
etc..
here's what i have so far but it only produces the permutations (doesn't capitalize anything)
var perm = function(str){
var results = [];
var combos = function(reference, appendTo){
appendTo = appendTo || "";
if(reference.length === 0) {
results.push(appendTo);
}
for(var i = 0; i < reference.length; i++){
var current = reference.splice(i, 1);
combos(reference, appendTo+current);
reference.splice(i, 0, current)
}
}
combos(str.split(""));
return results;
}
perm("word");
One option would be generating capitalization permutations via binary logic.
As a simple example of the snippet below, consider the following table where the left column is the binary representation of the current permutation and the right column is the resulting capitalization:
0000 | word
1000 | Word
0100 | wOrd
1100 | WOrd
...
1111 | WORD
// Used to display the results
const write = (msg) => {
document.body.appendChild(document.createElement('div')).innerHTML = msg;
};
const input = "word";
const letters = input.split("");
const permCount = 1 << input.length;
for (let perm = 0; perm < permCount; perm++) {
// Update the capitalization depending on the current permutation
letters.reduce((perm, letter, i) => {
letters[i] = (perm & 1) ? letter.toUpperCase() : letter.toLowerCase();
return perm >> 1;
}, perm);
const result = letters.join("");
write(result);
}
Note that theoretically this approach would work all the way up to Number.MAX_SAFE_INTEGER, up to inputs of length 52, but realistically you'll run into performance issues.
var s = "word";
var sp = s.split("");
for (var i = 0, l = 1 << s.length; i < l; i++) {
for (var j = i, k = 0; j; j >>= 1, k++) {
sp[k] = (j & 1) ? sp[k].toUpperCase() : sp[k].toLowerCase();
}
var st = sp.join("");
var d = document.createElement("p");
d.appendChild(document.createTextNode(st));
document.body.appendChild(d);
}
With Nit's solution in mind, I wanted to offer a slightly refactored solution that may be easier to follow
var perm = function(str){
var results = [];
var arr = str.split("");
var len = Math.pow(arr.length, 2);
for( var i = 0; i < len; i++ ){
for( var k= 0, j = i; k < arr.length; k++, j >>=1){
arr[k] = ( j & 1 ) ? arr[k].toUpperCase() : arr[k].toLowerCase();
}
var combo = arr.join("");
results.push(combo);
}
return results;
}
perm("word");
// NOT AN ANWSER JUST WANT TO RUN CODE ON CHROMEBOOK
// Used to display the results
const write = (msg) => {
document.body.appendChild(document.createElement('div')).innerHTML = msg;
};
const input = "word";
const letters = input.split("");
const permCount = 1 << input.length;
for (let perm = 0; perm < permCount; perm++) {
// Update the capitalization depending on the current permutation
letters.reduce((perm, letter, i) => {
letters[i] = (perm & 1) ? letter.toUpperCase() : letter.toLowerCase();
return perm >> 1;
}, perm);
const result = letters.join("");
write(result);
}
Related
Javascript Vernam Cipher - ensure output between unicode 32 and 126
I've implemented the below as mask for some data: function jEncryptDecrypt(data,key) { let jKey = '' let bytKey = []; let bytData = []; for (let i = 1; i < (data.length/key.length) +1; i++) { jKey = jKey + key; } let str = jKey.substring(0, data.length); for (let i = 0; i < str.length; ++i) { var code = str.charCodeAt(i); bytKey = bytKey.concat([code & 0xff, code / 256 >>> 0]); } let str2 = data for (let i = 0; i < str2.length; ++i) { var code = str2.charCodeAt(i); bytData = bytData.concat([code & 0xff, code / 256 >>> 0]); } for (let i = 0; i < bytData.length; ++i) { bytData[i] = bytData[i] ^ bytKey[i]; } str3 = String.fromCharCode(...bytData) str3 = str3.replace(/\0/g, ''); return str3; } For some outputs the bytes in bytData map to escape characters - depending on where I run the code I either get the character (JSFiddle) or I get \uXXXX (third party application). The output could end up being dealt with on different platforms/languages, so ideally I'd like to avoid special characters and just have characters in the 32 to 126 unicode range? Is this possible? The application I'm implementing this in is pretty restrictive, so I can't use any libraries, just pure JS. Edit I've changed the code to the below, which outputs an array of numbers on the encrypt, and accepts them as an input on the decrypt function jEncryptDecrypt(data,key) { let jKey = '' let bytKey = []; let bytData = []; //expand key to cover length of input for (let i = 1; i < (data.length/key.length) +1; i++) { jKey = jKey + key; } //shorten key to same lenght as input let str = jKey.substring(0, data.length); //loop over key to create array of numbers from unicode value for (let i = 0; i < str.length; ++i) { var code = str.charCodeAt(i); bytKey = bytKey.concat([code & 0xff, code / 256 >>> 0]); } //if data input is array no need to do anything if (Array.isArray(data)) { bytData = data; //otherwise loop over data to create array of numbers from unicode value } else { let str2 = data for (let i = 0; i < str2.length; ++i) { var code = str2.charCodeAt(i); bytData = bytData.concat([code & 0xff, code / 256 >>> 0]); } } //XOR each data value with each key value in turn for (let i = 0; i < bytData.length; ++i) { bytData[i] = (bytData[i] ^ bytKey[i]); } //if input was array return string, otherwise return array if (Array.isArray(data)) { str3 = String.fromCharCode(...bytData) str3 = str3.replace(/\0/g, ''); return str3; } else { return bytData; } } It's clunky and hacky but works for my needs. If there is an answer to the original question that would still be much appreciated!
Facing issue while reading stdin in node
I just registered in HackerEarth and trying to solve the first basic problem: Monk and rotation. When I am running the code by entering single input it works fine but when I submit the solution it does not work. https://www.hackerearth.com/practice/codemonk/ It seems I am reading the input incorrectly Can someone please help. process.stdin.resume(); process.stdin.setEncoding("utf-8"); var stdin_input = ""; process.stdin.on("data", function (input) { stdin_input += input; // Reading input from STDIN }); process.stdin.on("end", function () { let lines = stdin_input.split('\n'); let len = lines.length; let inputArr = []; const numberTestCase = lines[0] const output = new Array() for (i = 1; i < lines.length; i++) { let lineInput = lines[i].split(' '); let noOfElement = 0; let stepRotation = 0; let skipLineUpto = 0; let inputData = false; if (lineInput.length === 2) { inputData = true; noOfElement = lineInput[0] stepRotation = lineInput[1] skipLineUpto = parseInt(i) + 2; } if (inputData) { let stringOfArray = lines[i + 1]; let arrayData = stringOfArray.split(' '); let mod = 0 mod = stepRotation % noOfElement; if (mod != 0) { let unReversedArray = arrayData.splice(-mod); let ff = unReversedArray.concat(arrayData) inputArr.push(ff.join(' ')) } else { let ff = arrayData console.log(ff.join(' ')) inputArr.push(ff.join(' ')) } } } main(inputArr) }); function main(input) { process.stdout.write(input.join("\n")); // Writing output to STDOUT }
When you submit you can see why your code is not valid. Your solution is for when scenarios where input is 3 lines (1 test case), like in their example, but you can see their test cases where they have inputs of multiple lines (T test cases). Without any prototype method something like this would work (not working because time exceeded): let lines = stdin_input.split('\n'); let loops = lines[0]; for(i = 1; i < lines.length; i+=2) { let steps = lines[i].split(' ')[1]; let arr = lines[i+1].split(' '); for (j = 0; j < steps; j++) { var x = arr[arr.length-1], i; for (k = arr.length-1; k > 0; k--) { arr[k] = arr[k-1]; } arr[0] = x; } main(arr); } With pop() and unshift() only one test case is failing due to time exceeded but should get you close to the final solution: let lines = stdin_input.split('\n'); let loops = lines[0]; for(i = 1; i < lines.length; i+=2) { let steps = lines[i].split(' ')[1]; let arr = lines[i+1].split(' '); for (j = 0; j < steps; j++) { arr.unshift(arr.pop()); } main(arr); }
Character with longest consecutive repetition
i think i have wirtten the correct code for the problem only one thing and it that i return the first longest sequence how can i alter that to return the last maximum sequence? an example from codewars editor : for input '00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz' Expected: ['c', 19], instead got: ['0', 19] here is my code: function longestRepetition(s) { var count = 0; var temp = s.charAt(0); var arr = []; for (var i = 0; i < s.length; i++) { if (temp === s.charAt(i)) { count++ temp = s.charAt(i) } else { temp = s.charAt(i); arr.push(count) count = 1; } if(i==s.length-1) arr.push(count); } if(arr.length>0) { var Max=arr[0] for(var i=0;i<arr.length;i++) { if(Max<=arr[i]) Max=arr[i]; } } else var Max=0; var mindex=arr.indexOf(Max); return [s.charAt(mindex),Max] }
I think this would be easier with a regular expression. Match any character, then backreference that character as many times as you can. Then, you'll have an array of all the sequential sequences, eg ['000', 'aaaaa']. Map each string to its length and pass into Math.max, and you'll know how long the longest sequence is. Lastly, filter the sequences by those which have that much length, and return the last item in the filtered array: function longestRepetition(s) { const repeatedChars = s.match(/(.)\1*/g); const longestLength = Math.max(...repeatedChars.map(str => str.length)); const longestChars = repeatedChars.filter(str => str.length === longestLength); return [longestChars.pop(), longestLength]; } console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The issue in your code is that minindex is an index in your arr, but that index has nothing to do with s. So s.charAt(minindex) makes no sense. You should maintain for which character you had found the count. For instance you could push in arr both the count and the corresponding character (as a subarray with two values). Then the rest of your code would only need little modification to make it work. Applying this idea to your code without changing anything else, we get this: function longestRepetition(s) { var count = 0; var temp = s.charAt(0); var arr = []; for (var i = 0; i < s.length; i++) { if (temp === s.charAt(i)) { count++ temp = s.charAt(i) // Not necessary: was already equal } else { arr.push([temp, count]); // <--- pair, BEFORE changing temp temp = s.charAt(i); count = 1; } if(i==s.length-1) arr.push([temp, count]); // <--- } if(arr.length>0) { var Max=arr[0]; // <-- Max is now a pair of char & count for(var i=0;i<arr.length;i++) { if(Max[1]<arr[i][1]) // Comparison changed to just less-than Max=arr[i]; } } else Max=[null, 0]; // Must be a pair here also return Max; // Just return the pair } console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz')); But you can do the same with less code: function longestRepetition(s) { let result = [null, 0]; // pair of character and count for (var i = 0; i < s.length; null) { let start = i++; while (i < s.length && s[i] === s[start]) i++; // Find end of series if (i - start > result[1]) result = [s[start], i - start]; } return result; } console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The solution below answers the question with O(n) runtime: function longestRepetition(s) { let count = s.length > 0 ? 1 : 0 let char = s.length > 0 ? s[0] : '' for (let string_i = 0; string_i < s.length - 1; string_i += 1) { // keep track of current_char let current_char = s[string_i] let next_char = s[string_i + 1] // while the next char is same as current_char let tracker = 1 while (current_char === next_char) { // add one to tracker tracker += 1 string_i += 1 next_char = s[string_i + 1] } // if tracker greater than count if (tracker > count) { // returned char = current char // count =tracker count = tracker; char = current_char; } } return [char, count] } console.log(longestRepetition("bbbaaabaaaa"))//, ["a",4]
longest substring of non repeating characters javascript
The problems asks "given a string, find the longest non-repeating sub-string without repeating characters". I am a little stumped why returning my code is not working for the string "dvdf" for example. Here is my code : function lengthOfLongestSubstring(check) { var letters = check.split(""); var max = 0; var result = []; for (var i = 0; i < letters.length; i++) { var start = i if (result.indexOf(letters[i]) === -1) { result.push(letters[i]) } else { i = i - 1 result = [] } if (max === 0 || max < result.length) { max = result.length } } return max }
This implementation gives the correct result for "dvdf". It adds characters to current_string while there is no duplicate. When you find a duplicate cut current_string to the point of the duplicate. max is the max length current_string had at any time. This logic seems correct to me so I think it's correct. function lengthOfLongestSubstring(string) { var max = 0, current_string = "", i, char, pos; for (i = 0; i < string.length; i += 1) { char = string.charAt(i); pos = current_string.indexOf(char); if (pos !== -1) { // cut "dv" to "v" when you see another "d" current_string = current_string.substr(pos + 1); } current_string += char; max = Math.max(max, current_string.length); } return max; } lengthOfLongestSubstring("dvdf"); // 3 The value of current_string in each round is "", "d", "dv", "vd", "vdf".
By replacing the result array with a map storing the last index for each encountered character, you can modify the loop body to jump back to one after the last index of an identical character and continue your search from there instead of just restarting from the current position via currently i = i - 1 which fails in cases such as 'dvdf': Below is your code with changes to accommodate a map in place of an array: function lengthOfLongestSubstring(check) { var letters = check.split(""); var max = 0; var result = new Map(); var start = 0; for (var i = 0; i < letters.length; i++) { if (!result.has(letters[i])) { result.set(letters[i], i); } else { i = result.get(letters[i]); result.clear(); } if (max < result.size) { max = result.size; } } return max; } // Example: console.log(lengthOfLongestSubstring("dvdf")); // 3
Here's a solution using Sliding window and HashMap. var lengthOfLongestSubstring = function(str) { if (!!!str.length || typeof str !== 'string') return 0; if (str.length == 1) return 1; let hashTable = {}; let longestSubstringLength = 0; let start = 0; for (let i = 0; i < str.length; i++) { if (hashTable[str[i]] !== undefined && hashTable[str[i]] >= start) { start = hashTable[str[i]] + 1; } hashTable[str[i]] = i; longestSubstringLength = Math.max(longestSubstringLength, (i - start + 1)) } return longestSubstringLength; }
I figured out an easier solution: function longestSubstring(str) { let left = 0; let max = 0; let result = new Set(); for (let r = 0; r < str.length; r++) { //The code will check for an existing item on the set // If found, all the previously saved items will be deleted // the set will return to being empty while (result.has(str[r])) { result.delete(str[left]); left += 1; } result.add(str[r]); max = Math.max(max, r - left + 1); } console.log(result); return max; } console.log(longestSubstring('abcabccbc')); //3
Today (January 7th, 2021) this was the Leetcode question of the day. I initially used a solution very similar to the selected answer. Performance was okay but after reviewing the answer solution documentation I rewrote my answer using the sliding window technique (examples were only in Java and Python) since I was curious about how much of a performance improvement this would result in. It is slightly more performant (144ms versus 160ms) and has a lower memory footprint (42mb versus 44.9mb): function lengthOfLongestSubstring(s: string): number { let stringLength = s.length; let maxLength = 0; const charMap = new Map(); let pos = 0; for (let i = 0; i < stringLength; i++) { if (charMap.has(s[i])) { pos = Math.max(charMap.get(s[i]), pos); } maxLength = Math.max(maxLength, i - pos + 1); charMap.set(s[i], i + 1); } return maxLength; } console.log(lengthOfLongestSubstring("dvdf"));
Try this: function lengthOfLongestSubstring (str) { const map = new Map(); let max = 0; let left = 0; for (let right = 0; right < str.length; right++) { const char = str[right]; if (map.get(char) >= left) left = map.get(char) + 1; else max = Math.max(max, right - left + 1); map.set(char, right); } return max; }
You can try this: function lengthOfLongestSubstring(str) { let longest = ""; for (let i = 0; i < str.length; i++) { if (longest.includes(str[i])) { return longest.length } else { longest += str[i]; } } return longest.length; } console.log(lengthOfLongestSubstring("abcabcbb")); console.log(lengthOfLongestSubstring("bbbbb")); console.log(lengthOfLongestSubstring("abcdef")); console.log(lengthOfLongestSubstring(""));
reset i to i -1 is incorrect. you need another loop inside the for loop. you try something like this (i didn't check the index carefully). function lengthOfLongestSubstring(check){ var letters = check.split(""); var max = 0; for (var i = 0; i < letters.length; i++) { var result = []; var j = i; for(;j < letters.length; j++) { if (result.indexOf(letters[j]) === -1) { result.push(letters[j]); } else { break; } } if(j - i > max) { max = j - i; } } return max; }
You can try sliding window pattern to solve this problem. function lengthOfLongestSubstring(str) { let longest = 0; let longestStr = ""; let seen = {}; let start = 0; let next = 0; while (next < str.length) { // Take current character from string let char = str[next]; // If current character is already present in map if (seen[char]) { // Check if start index is greater than current character's last index start = Math.max(start, seen[char]); } // If new substring is longer than older if (longest < next - start + 1) { longest = next - start + 1; // Take slice of longer substring longestStr = str.slice(start, next + 1); } // Update current characters index seen[char] = next + 1; // Move to next character next++; } console.log(str, "->", longestStr, "->", longest); return longest; } lengthOfLongestSubstring("dvdfvev"); lengthOfLongestSubstring("hello"); lengthOfLongestSubstring("1212312344");
Find Longest Unique Substring using Map Method var str = "aaabcbdeaf"; var start = 0; var map = new Map(); var maxLength = 0; var longStr = ''; for(next =0; next< str.length ; next++){ if(map.has(str[next])){ map.set(str[next],map.get(str[next])+1); start = Math.max(start,map.get(str[next])); } if(maxLength < next-start+1){ maxLength = next-start+1; longStr = str.slice(start,next+1); } map.set(str[next],next); } console.log(longStr);
You can try something like that: function maxSubstring(s) { const array = [] const lengthS = s.length const pusher = (value) => { if (value !== '') { if (array.length > 0) { if (array.indexOf(value) === -1) { array.push(value) } } else { array.push(value) } } } pusher(s) for (const [index, value] of s.split('').entries()) { let length = lengthS let string = s const indexO = s.indexOf(value) pusher(value) while (length > indexO) { pusher(string.slice(index-1, length + 1)) length = --length } string = s.slice(index, lengthS) } array.sort() return array.pop() } console.log(maxSubstring('banana')) console.log(maxSubstring('fgjashore')) console.log(maxSubstring('xyzabcd'))
Find Longest unique substring without using MAP(). Just simple slice(). The same can be used to return longest unique string. Just replace "return max => return str" const string = "dvdf"; var lengthOfLongestSubstring = function() { if(string.length == 1) return 1; if(string.length == 0) return 0; let max = 0,i = 0, str = ""; while(i < string.length){ const index = str.indexOf(string.charAt(i)); if(index > -1) { // s = "fiterm".slice(1,4) => ite str = str.slice(index + 1, string.length); } str += string.charAt(i); max = Math.max(str.length, max); i++; } return max; };
Logest unqiue substring: function lengthOfLongestSubstring(s) { if(s.length < 2) { return s.length; } let longestLength = 1; let currentStr = ''; for(let i=0 ; i < s.length ; i++){ if(currentStr.includes(s.charAt(i))){ let firstSeen = currentStr.indexOf(s.charAt(i)); currentStr = currentStr.substring(firstSeen+1,currentStr.length); } currentStr += s.charAt(i); longestLength = Math.max(currentStr.length,longestLength); } return longestLength; };
One liner with reduce method. const subStrOfUniqueChar = str => [...str].reduce((p,c) => ( p.includes(c) ? (p += c, p.substr(p.indexOf(c)+1)) : p += c),''); console.log(subStrOfUniqueChar('dvdf').length);
function lengthOfLongestSubstring(s: string): number { const arr = s.split(""); let longest = 0; const set: Set<string> = new Set(); for (let i = 0; i < arr.length; i++) { set.add(arr[i]); let tryIndex = i + 1; while (arr[tryIndex] && !set.has(arr[tryIndex])) { set.add(arr[tryIndex]); tryIndex++; } if (set.size > longest) { longest = set.size; } set.clear(); } return longest; }
I wanted to toss my hat in this ring because I feel like I've found a pretty creative solution to this. No if/else blocks are needed as the substring.indexOf() will attempt to find the matching string character in the array and delete the indexes of the array up to, and including, the match (+1). If an indexOf() call finds no match it will return a -1, which added to +1 becomes a .splice(0,0) which will remove nothing. The final Math check factors in the last character addition in the loop to determine which outcome is higher. const findSubstring = string => { let substring = []; let maxCount = 0; for (let i = 0; i < string.length; i++) { maxCount = Math.max(substring.length, maxCount); substring.splice(0, substring.indexOf(string[i]) + 1); substring.push(string[i]); } maxCount = Math.max(substring.length, maxCount); return maxCount; }
uses sliding window concept function lengthOfLongestSubstring(s) { var letters = s.split(""); var subStr = ""; var result = []; var len = 0; let maxLen = 0; for (var i = 0; i < letters.length; i++) { const position = result.indexOf(letters[i]); if (position === -1) { result.push(letters[i]); len += 1; } else if (letters[i]) { result = result.splice(position + 1); len = result.length + 1; result.push(letters[i]); } maxLen = len > maxLen ? len : maxLen; } return maxLen; } console.log(lengthOfLongestSubstring(" "));
Sliding Window Technique O(n) you can use hash or Map in loop through string char Maintain dictionary of unique char if char exist in memory take clear hash update the count in longest variable and clear count start from first repeated char + 1 again. var lengthOfLongestSubstring = function(s) { if(s.length<2) return s.length; let longest = 0; let count=0; let hash={} for (let i = 0; i < s.length; i++) { //If char exist in hash if(hash[s[i]]!=undefined){ i=hash[s[i]]; hash={} longest = Math.max(longest, count); count = 0; }else{ hash[s[i]]=i count = count+1; } } return Math.max(longest, count); }; console.log(lengthOfLongestSubstring("abcabcbb")) console.log(lengthOfLongestSubstring("au"))
Sequential strings javascript
I'm stuck on sequential string generation, the last iteration of the code below, is trying to return ac. var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_'; var arr = []; var len = 1; var current = 0; for(var i = 0; i < 40; i++) { if(current == charcode.length) { current = 0 len++ } var tmpStr = '' for(var l = 0; l < len; l++) { tmpStr = tmpStr + charcode[current]; } console.log(tmpStr) current++ } However, it produces cc. Sorry, somehow deleted the intended output a, b, c ... aa, ab, ac ... ba, bc, bb ... ∞ My current understanding suggests within the l < len loop I should check if len > 1 and if so break out and loop for the current charcode[x] but I just can't wrap my head around breaking in and out as it grows.
You can do it like this: var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_'; var arr = []; var len = 0; var current = 0; for(var i = 0; i < 40; i++) { if(current == charcode.length) { current = 0; len++; } var tmpStr = (len===0) ? '' : charcode[len-1]; tmpStr = tmpStr + charcode[current]; current++; console.log(tmpStr); } In brief, you didn't need a second loop, but an iteration instead (which is achieved through charcode[len-1]). JS Bin here. UPDATE If you need a continuos loop until the very end of the charset, you can use this: This one introduces a third variable (digits) to the iteration and choses a .substr() instead of a single character out of the charset, so that everytime the end of the charset is reached, another digit will be added. The variable called x sets the limit. I have tried 4000 and it looks like it is working. var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_', arr = [], len = 0, digits = 2, current = 0, tmpStr = ''; var x = 4000; for(var i=0; i<x; i++) { if(current === charcode.length) { current = 0; len++; if(tmpStr.substr(0,1) === charcode.substr(-digits,1) || tmpStr === charcode.substr(-1) + '' + charcode.substr(-1)) { len = 1; digits++; } } if(digits === charcode.length) { console.log(charcode); console.log(i + ' results found'); break; } tmpStr = (len===0) ? '' : charcode.substr([len-1], digits-1); tmpStr += charcode[current]; current++; console.log(tmpStr); } Final JS Bin here.
Unless I'm failing to understand your question, which is highly likely, functional programming solves this problem in an incredibly easy way const stringSequence = xs => flatMap (x => map (add (x)) (xs)) (xs); let chars = 'abcdefghijklmnopqrstuvwxyz0123456789_' console.log (stringSequence (chars)); // ["aa","ab","ac","ad","ae","af","ag","ah","ai","aj","ak","al","am","an","ao","ap","aq","ar","as","at","au","av","aw","ax","ay","az","a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","a_","ba","bb","bc","bd","be","bf","bg","bh","bi","bj","bk","bl","bm","bn","bo","bp","bq","br","bs","bt","bu","bv","bw","bx","by","bz","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","b_","ca","cb","cc","cd","ce","cf","cg","ch","ci","cj","ck","cl","cm","cn","co","cp","cq","cr","cs","ct","cu","cv","cw","cx","cy","cz","c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","c_","da","db","dc","dd","de","df","dg","dh","di","dj","dk","dl","dm","dn","do","dp","dq","dr","ds","dt","du","dv","dw","dx","dy","dz","d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d_","ea","eb","ec","ed","ee","ef","eg","eh","ei","ej","ek","el","em","en","eo","ep","eq","er","es","et","eu","ev","ew","ex","ey","ez","e0","e1","e2","e3","e4","e5","e6","e7","e8","e9","e_","fa","fb","fc","fd","fe","ff","fg","fh","fi","fj","fk","fl","fm","fn","fo","fp","fq","fr","fs","ft","fu","fv","fw","fx","fy","fz","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","f_","ga","gb","gc","gd","ge","gf","gg","gh","gi","gj","gk","gl","gm","gn","go","gp","gq","gr","gs","gt","gu","gv","gw","gx","gy","gz","g0","g1","g2","g3","g4","g5","g6","g7","g8","g9","g_","ha","hb","hc","hd","he","hf","hg","hh","hi","hj","hk","hl","hm","hn","ho","hp","hq","hr","hs","ht","hu","hv","hw","hx","hy","hz","h0","h1","h2","h3","h4","h5","h6","h7","h8","h9","h_","ia","ib","ic","id","ie","if","ig","ih","ii","ij","ik","il","im","in","io","ip","iq","ir","is","it","iu","iv","iw","ix","iy","iz","i0","i1","i2","i3","i4","i5","i6","i7","i8","i9","i_","ja","jb","jc","jd","je","jf","jg","jh","ji","jj","jk","jl","jm","jn","jo","jp","jq","jr","js","jt","ju","jv","jw","jx","jy","jz","j0","j1","j2","j3","j4","j5","j6","j7","j8","j9","j_","ka","kb","kc","kd","ke","kf","kg","kh","ki","kj","kk","kl","km","kn","ko","kp","kq","kr","ks","kt","ku","kv","kw","kx","ky","kz","k0","k1","k2","k3","k4","k5","k6","k7","k8","k9","k_","la","lb","lc","ld","le","lf","lg","lh","li","lj","lk","ll","lm","ln","lo","lp","lq","lr","ls","lt","lu","lv","lw","lx","ly","lz","l0","l1","l2","l3","l4","l5","l6","l7","l8","l9","l_","ma","mb","mc","md","me","mf","mg","mh","mi","mj","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt","mu","mv","mw","mx","my","mz","m0","m1","m2","m3","m4","m5","m6","m7","m8","m9","m_","na","nb","nc","nd","ne","nf","ng","nh","ni","nj","nk","nl","nm","nn","no","np","nq","nr","ns","nt","nu","nv","nw","nx","ny","nz","n0","n1","n2","n3","n4","n5","n6","n7","n8","n9","n_","oa","ob","oc","od","oe","of","og","oh","oi","oj","ok","ol","om","on","oo","op","oq","or","os","ot","ou","ov","ow","ox","oy","oz","o0","o1","o2","o3","o4","o5","o6","o7","o8","o9","o_","pa","pb","pc","pd","pe","pf","pg","ph","pi","pj","pk","pl","pm","pn","po","pp","pq","pr","ps","pt","pu","pv","pw","px","py","pz","p0","p1","p2","p3","p4","p5","p6","p7","p8","p9","p_","qa","qb","qc","qd","qe","qf","qg","qh","qi","qj","qk","ql","qm","qn","qo","qp","qq","qr","qs","qt","qu","qv","qw","qx","qy","qz","q0","q1","q2","q3","q4","q5","q6","q7","q8","q9","q_","ra","rb","rc","rd","re","rf","rg","rh","ri","rj","rk","rl","rm","rn","ro","rp","rq","rr","rs","rt","ru","rv","rw","rx","ry","rz","r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r_","sa","sb","sc","sd","se","sf","sg","sh","si","sj","sk","sl","sm","sn","so","sp","sq","sr","ss","st","su","sv","sw","sx","sy","sz","s0","s1","s2","s3","s4","s5","s6","s7","s8","s9","s_","ta","tb","tc","td","te","tf","tg","th","ti","tj","tk","tl","tm","tn","to","tp","tq","tr","ts","tt","tu","tv","tw","tx","ty","tz","t0","t1","t2","t3","t4","t5","t6","t7","t8","t9","t_","ua","ub","uc","ud","ue","uf","ug","uh","ui","uj","uk","ul","um","un","uo","up","uq","ur","us","ut","uu","uv","uw","ux","uy","uz","u0","u1","u2","u3","u4","u5","u6","u7","u8","u9","u_","va","vb","vc","vd","ve","vf","vg","vh","vi","vj","vk","vl","vm","vn","vo","vp","vq","vr","vs","vt","vu","vv","vw","vx","vy","vz","v0","v1","v2","v3","v4","v5","v6","v7","v8","v9","v_","wa","wb","wc","wd","we","wf","wg","wh","wi","wj","wk","wl","wm","wn","wo","wp","wq","wr","ws","wt","wu","wv","ww","wx","wy","wz","w0","w1","w2","w3","w4","w5","w6","w7","w8","w9","w_","xa","xb","xc","xd","xe","xf","xg","xh","xi","xj","xk","xl","xm","xn","xo","xp","xq","xr","xs","xt","xu","xv","xw","xx","xy","xz","x0","x1","x2","x3","x4","x5","x6","x7","x8","x9","x_","ya","yb","yc","yd","ye","yf","yg","yh","yi","yj","yk","yl","ym","yn","yo","yp","yq","yr","ys","yt","yu","yv","yw","yx","yy","yz","y0","y1","y2","y3","y4","y5","y6","y7","y8","y9","y_","za","zb","zc","zd","ze","zf","zg","zh","zi","zj","zk","zl","zm","zn","zo","zp","zq","zr","zs","zt","zu","zv","zw","zx","zy","zz","z0","z1","z2","z3","z4","z5","z6","z7","z8","z9","z_","0a","0b","0c","0d","0e","0f","0g","0h","0i","0j","0k","0l","0m","0n","0o","0p","0q","0r","0s","0t","0u","0v","0w","0x","0y","0z","00","01","02","03","04","05","06","07","08","09","0_","1a","1b","1c","1d","1e","1f","1g","1h","1i","1j","1k","1l","1m","1n","1o","1p","1q","1r","1s","1t","1u","1v","1w","1x","1y","1z","10","11","12","13","14","15","16","17","18","19","1_","2a","2b","2c","2d","2e","2f","2g","2h","2i","2j","2k","2l","2m","2n","2o","2p","2q","2r","2s","2t","2u","2v","2w","2x","2y","2z","20","21","22","23","24","25","26","27","28","29","2_","3a","3b","3c","3d","3e","3f","3g","3h","3i","3j","3k","3l","3m","3n","3o","3p","3q","3r","3s","3t","3u","3v","3w","3x","3y","3z","30","31","32","33","34","35","36","37","38","39","3_","4a","4b","4c","4d","4e","4f","4g","4h","4i","4j","4k","4l","4m","4n","4o","4p","4q","4r","4s","4t","4u","4v","4w","4x","4y","4z","40","41","42","43","44","45","46","47","48","49","4_","5a","5b","5c","5d","5e","5f","5g","5h","5i","5j","5k","5l","5m","5n","5o","5p","5q","5r","5s","5t","5u","5v","5w","5x","5y","5z","50","51","52","53","54","55","56","57","58","59","5_","6a","6b","6c","6d","6e","6f","6g","6h","6i","6j","6k","6l","6m","6n","6o","6p","6q","6r","6s","6t","6u","6v","6w","6x","6y","6z","60","61","62","63","64","65","66","67","68","69","6_","7a","7b","7c","7d","7e","7f","7g","7h","7i","7j","7k","7l","7m","7n","7o","7p","7q","7r","7s","7t","7u","7v","7w","7x","7y","7z","70","71","72","73","74","75","76","77","78","79","7_","8a","8b","8c","8d","8e","8f","8g","8h","8i","8j","8k","8l","8m","8n","8o","8p","8q","8r","8s","8t","8u","8v","8w","8x","8y","8z","80","81","82","83","84","85","86","87","88","89","8_","9a","9b","9c","9d","9e","9f","9g","9h","9i","9j","9k","9l","9m","9n","9o","9p","9q","9r","9s","9t","9u","9v","9w","9x","9y","9z","90","91","92","93","94","95","96","97","98","99","9_","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","_s","_t","_u","_v","_w","_x","_y","_z","_0","_1","_2","_3","_4","_5","_6","_7","_8","_9","__"] Oh but you don't have flatMap? Easy, just make your own, as well as any other simple procedures that describe the computations you would like to perform const add = x => y => x + y; const map = f => xs => Array.prototype.map.call(xs, x => f (x)); const reduce = f => i => xs => Array.prototype.reduce.call(xs, (x,y) => f (x) (y)); const concat = xs => x => xs.concat(x); const flatMap = f => xs => reduce (concat) ([]) (map (f) (xs)); These procedures are highly reusable and free you from the shackles of imperative code that looks like this var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_'; // setup several state variables var arr = []; var len = 1; // 6 months later, why did we initialize len at 1? var current = 0; // manual looping, with arbitrary static input of 40 (why 40?) for(var i = 0; i < 40; i++) { // logic with potential for human error if(current == charcode.length) { // variable mutations current = 0 len++ } // temporary variables var tmpStr = '' // move manual looping for(var l = 0; l < len; l++) { // more variable mutation tmpStr = tmpStr + charcode[current]; } // IO side effects console.log(tmpStr) // manual iteration current++ }