Javascript - find all possible strings - javascript

Looking for some tips to solve this problem. We have string chain
const str = "543163431154",
and array with numbers where elements are basically numbers taken from this string
const array = ["21154", "543123", "163421154"]
What I'm looking for is to find all possible strings
Was thinking to split our input string as first, then create variable to store single letters. Subsequently I could iterate over newly created array in some kind of reduce function, but tbh I have no right solution

Here's an algorithm,
From your array, create 5 arrays, each one with different order of the elements from the original array
Iterate over each array
For each element, check using regex if the str starts with it (^currentElement)
If it is, remove from your str the current element and continue to the next element
If it's not, continue to the next array from the 5 you created
If you reach the last index of every array and str starts with it, add the current array to the results.
Here you go, now because it's not a code writing site and it's not a specific code question I wont write it for you - but the above algorithm will work for you.

Edit: After a bit more reading I understood the problem a bit better, and boy was this fun!
const str = "14316342115414321154"
const array = ["21154", "143", "21154143", "1634", "163421154"]
const findAllCombinations = (str, match) => {
const result = match.reduce((acc, layer) => {
if(str.indexOf(layer) === 0) {
if(str.substring(layer.length).length > 0) {
const nextLayer = findAllCombinations(str.substring(layer.length), match).map(c => addToLayer(layer, c))
acc.push(...nextLayer)
} else {
acc.push(addToLayer(layer, ""))
}
}
return acc;
}, [])
return result
}
const addToLayer = (layer, add) => `:${layer}${add}`
console.log(findAllCombinations(str,array))

Related

Checking if the array has duplicates apart from one element Javascript Dice

Hi im struggling to impliment a function to simply check if an array has all the same numbers apart from one.
I have tried a few methods now and i feel like im getting nowhere.
The reason for this is for a dice game the user can select a number of dices and then roll and score bonus points for duplicate numbers and other sequences ect..
I thought it would be simple to check if the array had all duplciates apart from one element in the array but i cant get it to work.
I was thinking of something like check the elements in the aray and see if the all the elements are the same value apart from one by using something with the array.length-1.
Examples dice values which would be true:
[1,2,2,2] or [4,4,2,4] (for 4 dice) //true
[1,1,6] (for 3 dice )//true
I tried something like this :
function countDuplicate(array){
var count=0;
var sorted_array=array.sort();
for (let i=1;i<sorted_array.length;i++)
{
if (sorted_array[i] ==sorted_array[i+1]){
count+=count;}
}
if (count===sorted_array.length-1){
return true;
}
return false;
}
but it doesnt seem to work.
Hope this is enough sorry im new to javascript and stackoverflow.
One way to implement this is to build an array of counts of each of the values in the array. This list can then be checked to ensure its length is 2 and the minimum count is 1:
const countDuplicate = (array) => {
let counts = Object.values(array.reduce((c, v) =>
(c[v] = (c[v] || 0) + 1, c), {}));
return counts.length == 2 && Math.min(...counts) == 1
}
console.log(countDuplicate([1,2,2,2]));
console.log(countDuplicate([4,4,2,4]));
console.log(countDuplicate([1,1,6]));
console.log(countDuplicate([2,2,4,4]));
console.log(countDuplicate([1,2]));
This is using Set and it compares the length of original array and array of removed duplicates:
const hasDuplicates = (arr = []) => {
const noDuplicates = [...new Set(arr)];
return arr.length !== noDuplicates.length;
};
console.log(hasDuplicates([1,2,3]));
console.log(hasDuplicates([1,2,3,1]));
if you're simply just wanting to check if all values are the same except for one in array you can just use this.
function oneMultiple(array) {
const set = new Set(array)
return set.size === 2
}
if you want to simply use one values USE THIS
function oneMultiple(array) {
const set = new Set(array)
return set.size === 2
}

Finding the Anagrams of a word from a list- codewars question

I am pretty new to programming and I was solving a problem on code wars which is as follows:
Question:
Write a function that will find all the anagrams of a word from a list. You will be given two inputs a word and an array with words. You should return an array of all the anagrams or an empty array if there are none.
This is my code
function anagrams(word, words) {
let word_Array = word.split('').sort()
let total = []
for (x = 0; x<words.length; x++) {
if(words[x].split('').sort() === word_Array) {
total.push(words[x])
} return total
}
}
The result should look something like this
anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) => ['aabb', 'bbaa']
I keep getting an empty array when I run my code. Please can someone tell me the error in my code. Thank you
Please take a look at the following snippet.
const sort = (word) => word.split('').sort().join('');
function anagrams(word, words) {
let token = sort(word);
let total = []
for (let x = 0; x < words.length; x++) {
if (sort(words[x]) === token) {
total.push(words[x])
}
}
return total
}
console.log(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']));
You are on the right track but missed a few details.
As others have mentioned you cant just compare discrete arrays with ===. The best you can do is an element wise compare. You dont really need to this if you compare normal value types such as numbers, strings, bools, ect. If you join the sorted string back its much easier to compare using built in operators such as ===.
Your control logic is wrong. Notice how you are returning straight from the loop? It means that at most you would ever get one results since the loop cant iterative over the full loop condition.
You should always qualify your variable declarations with let/const. This was missing in the for loop and would declare x as a global.
Improvements
You could replace the for loop with a for of and not have to worry about indexing.
for (let w of words) {
console.log(w); // we no longer have to worry about words[i].
}
Even better you could replace the entire for and array.push logic with a simple array.filter
const sort = (word) => word.split('').sort().join('');
function anagrams(word, words) {
let token = sort(word);
return words.filter((w) => sort(w) === token);
}
console.log(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']));
Array is Object in JavaScript, which is reference type.
So you can not use "===" to check whether two arrays are equals.
For example:
var array1=[1,2];
var array2=[1,2];
var result = array1 === array2;
the result will be false.
My suggestion is writing a new function to check whether two arrays are equals by comparing the items.
function areEquals(array1, array2){
if(array1.length!==array2.length){
return false;
}
for(var i in array1){
if(array1[i]!==array2[i]){
return false;
}
}
return true;
}

Find word in string using RegEx javascript

How can I make a search function using regEx?
I have some code but can't post it at the moment due to my computer being very broken and annoying, I will try again tomorrow!
This is not really what would be called combinations, but permutations.
The idea is to use recursion for getting the result for a shorter array, i.e. the one that lacks the first element.
Then take all permutations you get back from the recursive call, and insert the left-out value in each possible index.
When input has duplicates, then you need to stop inserting the left-out value as soon as you find that same value preceding the insertion spot.
Here is how that looks:
function scramble(array) {
if (array.length == 0) {
return [[]];
}
let results = [];
// solve the problem for a shorter array (first value excluded), and iterate:
for (let perm of scramble(array.slice(1))) {
// add the missing element in each possible position:
for (let i = 0; i < array.length; i++) {
// next IF is only needed when input has duplicates, and
// output should not repeat same array:
if (i && array[0] === perm[i-1]) break;
results.push(perm.slice(0, i).concat(array[0], perm.slice(i)));
}
}
return results;
}
let array = ["I", "am", "coding", "am"];
console.log(scramble(array));
Without the inner if, an input with duplicate values will produce duplicate arrays. If this is not desired, then the if is needed.
You could iterate and get a flat array of the mapping of the value with the result of the nested calls.
function permutation(array) {
return array.length === 1
? [array]
: array.flatMap((v, i) => permutation([
...array.slice(0, i),
...array.slice(i + 1)
]).map(a => [v, ...a]));
}
permutation(["I", "am", "coding"]).map(a => console.log(...a));

Splitting an array of numbers and non-numbers into two separate arrays

I'm very new to javascript and I'm trying to create a function that takes a mixed input of numbers and then loops through the array in order to sort them into two newer arrays so I can manipulate them further.
So if I have an input of
1,a,2,b,3,c,4,d,
I want to make two new arrays of
1,2,3,4 and a,b,c,d
So far I've been able to split the input string at the comma, so that I now have
1a2b3c4d
all I need to be able to do now is just separate the numbers and non-numbers. I was thinking of using two loops: one that checks
if(isNan.array[n] == True )
and then trying to find a way to store the letters into a variable using the loop and then using another loop to do so for the numbers using another if function.
Is this how I should do it, and do you have any advice on how to go about it?
Edit:
I now have this code to check for letters:
if (isNaN(splitResult[L])) {
for (i = 0; i < splitResult; i++) {
letterArray.add(splitResult[L]);
L = L + 1
When I try to output the results to a box to count letters (using the variable L), nothing shows up. I doubt I've made a new array
just for completion, split the string into array first :)
let yourString = '1a2b3c4d';
let yourArray = yourString.split('');
let letterArray = [];
let numberArray = [];
yourArray.forEach(item => {
if(isNaN(item) && typeof item === 'string'){
letterArray.push(item);
}
else if(!isNaN(item) {
numberArray.push(item);
}
});
console.log(letterArray, numberArray);
All you need to do is loop through the array, you can use the Array prototypes forEach. Or you can use the normal for loop to check through each element of the array. You can now check if each element isNaN and then push into the right array appropriately. You can use the snippet below
const yourArray = ['1','a','2','b','3','c','4','d'];
const letterArray = [];
const numberArray = [];
yourArray.forEach((eachItem) => {
if(isNaN(eachItem)){
letterArray.push(eachItem);
} else {
numberArray.push(eachItem);
}
});
console.log(letterArray, numberArray);

Looping through an array with conditions

I'm having a tough time figuring out how to loop through an array and if certain items do exist within the array, i'd like to perform a .slice(0, 16) to kind of filter an already existing array (lets call that existing array "routes").
For example, a previous process will yield the following array:
points = ['=00ECY20WA200_RECV_P1SEL',
'=00ECY20WA200_RECV_P2SEL',
'=00RECV_C1A_EINCSCMPP1',
'=00RECV_C1A_EINCSCMPP2',
'=00BYPS_C1A_EINCSCMP',
'=00ECY20WA200_BYPS_SPSL1',
'=00ECC92AG184YB01',
'=00ECC92AG185YB01',
'=00ECC92AG186YB01',
'=00ECC92AG187YB01',
]
So if any of the above items exist in the "points" Array, which in this case they all do (but in some cases it could just be 1 of the 10 items existing there), I'm trying to perform routes.slice(0, 16) to the other already existing array.
I've tried lots of different ways (for loops with if statements) and at this point I'm not sure if its my syntax or what, but I'm back at square 0 and I don't even have a competent piece of code to show for. Any direction would be greatly appreciated.
You could use a hash table for checking and filtering.
var points = ['=00ECY20WA200_RECV_P1SEL', '=00ECY20WA200_RECV_P2SEL', '=00RECV_C1A_EINCSCMPP1', '=00RECV_C1A_EINCSCMPP2', '=00BYPS_C1A_EINCSCMP', '=00ECY20WA200_BYPS_SPSL1', '=00ECC92AG184YB01', '=00ECC92AG185YB01', '=00ECC92AG186YB01', '=00ECC92AG187YB01'],
hash = Object.create(null),
filtered = points.filter(function (a) {
if (!hash[a.slice(0, 16)]) {
hash[a.slice(0, 16)] = true;
return true;
}
});
console.log(filtered);
ES6 with Set
var points = ['=00ECY20WA200_RECV_P1SEL', '=00ECY20WA200_RECV_P2SEL', '=00RECV_C1A_EINCSCMPP1', '=00RECV_C1A_EINCSCMPP2', '=00BYPS_C1A_EINCSCMP', '=00ECY20WA200_BYPS_SPSL1', '=00ECC92AG184YB01', '=00ECC92AG185YB01', '=00ECC92AG186YB01', '=00ECC92AG187YB01'],
pSet = new Set,
filtered = points.filter(a => !pSet.has(a.slice(0, 16)) && pSet.add(a.slice(0, 16)));
console.log(filtered);
EDIT: So it seems like you want to remove an element from an array called routes for each element in the points array. This is how you could do this:
function removeBrokenRoutes(brokenPoints, routes){
for(let pt of brokenPoints){
let index = routes.indexOf(pt);
if(index !== -1) routes.splice(index,1);
}
return routes;
}
Keep in mind that the larger the arrays, the more time this is going to take to complete.
You could use the filter and indexOf methods in combination:
var arr = [/* all the data you're checking against */];
var points = [/* the data you're checking for */];
var filteredArr = arr.filter(function(x) {
// will return -1 if the point is not found
return points.indexOf(x) !== -1;
});
filteredArr will contain all the points that appear in both arrays. The filter function works by taking a function with one argument x, which represents each item in the array. if the function returns true, the item will be added to the new array (filteredArr), and if false the function will move on to the next item. indexOf will check if the item is found in the other array. Also it is important to note that you will need a more complex solution (such as a hashtable) if the data set is very, very large as this is not necessarily the most performant method. But it's a good place to start as it is easy to understand.

Categories

Resources