I am trying to write a function that will take an array and n as parameters,
it will return all subsets of that array with n elements, have tried a couple things, couldn't yet succeed.
thanks to whoever put it here, this functions is way too complicated and doesn't do the job, basically what I tried to do here is to pick out one element from a 4 element array to create its 3 element subsets. It doesn't even take N as parameter. it returns all 3 element subsets but also identical ones, so I have to filter them out as well, in any case I will keep trying.
function findSubsets(array) {
var answers = [];
var firstArray = array;
for (i = 0; i < array.length; i++) {
array = firstArray;
for (var k = 0; k < array.length; k++) {
if (k != i) {
var subset = array.splice(k, 1);
answers.push(array); array.splice(k, 0, subset[0]);
}
}
}
}
That not as complicated as it seems. This one is optimized because it doesn't creates useless temporary arrays during the process.
function findSubsets(array, n) {
var answers = [];
for(var i = 0 ; i < array.length ; i += n) {
answers.push(array.slice(i, i + n));
}
return answers;
}
findSubsets([1, 2, 3, 4, 5, 6, 7, 8, 9], 2) // --> [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
findSubsets([1, 2, 3, 4, 5, 6, 7, 8, 9], 3) // --> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
You can try this solution
var subsetArray = (function() {
return {
getResult: getResult
}
function getResult(array, n) {
function isBigEnough(value) {
return value.length === n;
}
var ps = [
[]
];
for (var i = 0; i < array.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(array[i]));
}
}
return ps.filter(isBigEnough);
}
})();
var arr = [1, 2, 3, 4,5,6,7,8,9];
console.log(subsetArray.getResult(arr,2));
Related
I am working on a 4x4 sudoku program. I am trying to loop through the column of 2d array and returning false if an elements is not present otherwise return true. I have checked using console.log and my function is only looping through the first item and returning true.
Here is my code:
function linearSearch(array, item) {
var n = array.length;
for (var i = 0; i < n; i++) {
if (array[i] == item) {
return true;
}
}
return false;
}
function checkColumn(puzzle, j) {
//first make an array out of the values stored in column j
let check = [];
//call linearSearch on the array of column
//values for all values of k from 1 to 4
for (var i = 0; i < puzzle.length; i++) {
check.push(puzzle[i][j]);
}
console.log(check);
for (var i = 0; i < check.length; i++) {
if (linearSearch(check, check[i])) {
console.log(i, check[i])
return true;
}
}
return false;
}
var puzzle1 = [
[1, 2, 3, 4],
[2, 3, 4, 1],
[2, 3, 4, 1],
[4, 1, 2, 3]
];
console.log(checkColumn(puzzle1, 2));
var puzzle = [
[1, 2, 3, 4],
[2, 3, 4, 1],
[3, 4, 1, 2],
[4, 1, 2, 3]
];
console.log(checkColumn(puzzle, 1));
any help would be appreciated thanks
In checkColumn in the second loop, you put return true that breaks the loop because your linearSearch return true allways:
for (var i = 0; i < check.length; i++) {
if (linearSearch(check, check[i])) {
console.log(i, check[i])
return true;
}
}
I have a multidimensional array that returns undefined after the last value of every sub-array. Here is my code:
var bigArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
];
for (i = 0; i < bigArray.length; i++) {
for (j = 0; j <= bigArray[i].length; j++) {
console.log(bigArray[i][j]);
}
}
Remove the = part from the condition of the second loop. You tries to access an element out of the range of the array. Also declare your variables with var, let or const - in the case with i and j.
var bigArray = [
[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]
];
for(var i = 0; i < bigArray.length; i++) {
for(var j = 0; j < bigArray[i].length; j++) {
console.log(bigArray[i][j]);
}
}
In this case, '.length' method will return the total number elements in that array, But array index starts from 0. So if an array contains n elements the array index of the last element will be n-1. And if you are trying to access an array with index n it will return an ArrayIndexOutOfBound Exception.
You can try this code
var bigArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
];
for (i = 0; i <= bigArray.length-1; i++) {
for (j = 0; j <= bigArray[i].length-1; j++) {
console.log(bigArray[i][j]);
}
}
I am trying to write a function that prints only the even numbers from a nested array. Here is my attempt and it keeps returning "undefined".
function printEvents(){
var nestedArr = [[1,2,3],[4,5,6],[7,8],[9,10,11,12]];
for (var i = 0; i<nestedArr.length; i++) {
for (var j = 0; j<nestedArr[i]; j++) {
var evenNumbers = nestedArr[i][j]
}
}
if (evenNumbers % 2 == 0) {
console.log(evenNumbers)
}
}
printEvents();
You could use a recursive approach, if the item is an array. You need to move the test for evenness inside of the for loop.
function printEvents(array) {
var i;
for (i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
printEvents(array[i]);
continue;
}
if (array[i] % 2 == 0) {
console.log(array[i]);
}
}
}
printEvents([[1, 2, 3], [4, 5, 6], [7, 8], [9, 10, 11, 12], [[[13, [14]]]]]);
Solution with a callback
function getEven(a) {
if (Array.isArray(a)) {
a.forEach(getEven);
return;
}
if (a % 2 == 0) {
console.log(a);
}
}
getEven([[1, 2, 3], [4, 5, 6], [7, 8], [9, 10, 11, 12], [[[13, [14]]]]]);
You just have a couple issues. You need to check the length of your nested arrays and you need to move your code that checks whether a number is even or not inside the array.
var nestedArr = [[1,2,3],[4,5,6],[7,8],[9,10,11,12]];
for (var i = 0; i<nestedArr.length; i++) {
for (var j = 0; j<nestedArr[i].length; j++) {
var evenNumbers = nestedArr[i][j]
if (evenNumbers % 2 == 0) {
console.log(evenNumbers)
}
}
}
You can do this more easy using filter method which accepts a callback method.
var nestedArr = [[1,2,3],[4,5,6],[7,8],[9,10,11,12]];
var mergedArray=[].concat.apply([], nestedArr);
console.log(mergedArray.filter(a => a%2 == 0));
You can use reduce with every for something quick.
var nestedArr = [ [1, 2, 3],[4, 5, 6],[7, 8],[9, 10, 11, 12]];
var sift = nestedArr.reduce(function(r,o) {
o.every(i => i % 2 === 0 ? r.push(i) : true)
return r;
}, []);
console.log(sift);
If you want a one-liner you can use ReduceRight with Filter
var nestedArr = [[1, 2, 3],[4, 5, 6],[7, 8],[9, 10, 11, 12]];
var sift = nestedArr.reduceRight((p, b) => p.concat(b).filter(x => x % 2 === 0), []);
console.log(sift)
What is a fast way to find combinations that aren't present in an array yet?
E.g, I have list of points: [1, 2, 4, 9]
And I have a list of connections [[1,2], [1,4], [1,9], [2,4], [4,9]]
So the missing connection in this list is [2,9]. As there is one requirement: every integer must be connected to a bigger integer.
var points = [1, 2, 4, 9];
var connections = [[1,2], [1,4], [1,9], [2,4], [4,9]];
var missing = [];
for(i = 0; i < points.length; i++){
for(j = i + 1; j < points.length; j++){
var found = false;
for(var a = 0; a < connections.length; a++){
if(connections[a][0] == points[i] && connections[a][1] == points[j]){
found = true;
break;
}
}
if(!found) missing.push([points[i], points[j]]);
}
}
console.log(missing);
The above code works, but the amount of for loops makes me think it is reasonably slow. Is there any faster way to do this? View jsfiddle
By sorting the array, you can do it with 2 nests. Sorting takes O(n log n), and the loops are basically O(n ^ 2).
var points = [1, 2, 4, 9];
var connections = [
[1, 2],
[1, 4],
[1, 9],
[2, 4],
[4, 9]
];
connections.sort();
var missing = [];
var currentIndex = 0;
for (var i = 0; i < points.length; i++) {
for (var j = i + 1; j < points.length; j++) {
if (connections[currentIndex][0] == points[i] && connections[currentIndex][1] == points[j]) {
currentIndex++;
} else {
missing.push([points[i], points[j]]);
}
}
}
console.log(missing);
You can use .reduce method in order to generate all the combination of two elements.Then the only thing that will remain is to get the difference from two arrays.
For this, you can use filter method which accepts a callback method.
var points = [1, 2, 4, 9];
points=points.sort();
var connections = [[1,2], [1,4], [1,9], [2,4], [4,9]];
var combinations = points.reduce(function(arr,elem,i){
for(j=i+1;j<points.length;j++)
arr.push([elem,points[j]]);
return arr;
},[]);
var diff=combinations.filter(function(elem,i){
return connections.find(a=>a[0]==elem[0] && a[1]==elem[1])==undefined;
});
console.log(diff);
You could iterate only the outer loop until length - 2 and use a hash table for inserted connections. The sort order of connections does not matter.
var points = [1, 2, 4, 9],
connections = [[1, 2], [1, 4], [1, 9], [2, 4], [4, 9]],
missing = [],
i, j,
pair,
connected = Object.create(null);
connections.forEach(function (a) {
connected[a.join()] = true;
});
for (i = 0; i < points.length - 1; i++) {
for (j = i + 1; j < points.length; j++) {
pair = [points[i], points[j]];
connected[pair.join()] || missing.push(pair);
}
}
console.log(missing);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I'm building an app to test different icons. Admins upload a number of icons and input how many icons must be shown at the same time. The app then displays all possible sets of icons in sequence until all combination of icons have been shown.
Now, I need a function to generate all unique icons combinations based on two number:
the number of total icons (i)
the number of icons in each set (s)
If i = 6 and s = 3, I want the output to look as follows:
[
[1, 2, 3],
[1, 2, 4],
[1, 2, 5],
[1, 2, 6],
[1, 3, 4],
[1, 3, 5],
[1, 3, 6],
[1, 4, 5],
[1, 4, 6],
[1, 5, 6],
[2, 3, 4],
[2, 3, 5],
[2, 3, 6],
[2, 4, 5],
[2, 4, 6],
[2, 5, 6],
[3, 4, 5],
[3, 4, 6],
[3, 5, 6],
[4, 5, 6],
]
Requirements:
All sets have to be unique
A number can only occur one time in a set
I have been trying to code a recursive function, but I havent anything really anything to show. I can't get my head around it :(
Based off the idea given as an answer to this question:
Computing all n-sized permutations without repetitions and without "classic" ordering
Then use C++ std::next_permutation like algorithms which work as
follows:
Go from left and find rightmost one preceeded by zero. Put one in
place of zero and sort the rest of array.
Disclaimer: My javascript is very, very rusty so I'm sure there is a much more elegant way of implementing this.
function combine(n, k) {
var result = [];
// initialize array of values
var values = [];
for (var i = 1; i <= n; i++) {
values[i - 1] = i;
}
// initialize permutations
var perm = [];
for (var i = 0; i < n; i++) {
if (i < k) {
perm[i] = 1;
} else {
perm[i] = 0;
}
}
perm.sort();
whileloop:
while (true) {
// save subresult
var subresult = [];
for (var i = 0; i < n; i++) {
if (perm[i] == 1) {
subresult.push(values[i]);
}
}
result.push(subresult);
// get next permutation
for (var i = n - 1; i > 0; i--) {
if (perm[i - 1] == 1) {
continue;
}
if (perm[i] == 1) {
perm[i - 1] = 1;
perm[i] = 0;
perm = perm.slice(0, i).concat(perm.slice(i).sort())
continue whileloop;
}
}
// no additional permutations exist
break whileloop;
}
return result;
}
Combining n elements in to number of sets with k elements each without repetitions, how to do it.
The algorithm is relatively simple, main idea: we consequently feed first set of k elements and then try to increment each element from the end of set to populate another k-set and so on.
When we can't do that we leave the process (all possible sets are ready).
function combine(n,k) {
var result = Array();
var a = Array();
// make initial (first) k-set
for (var i=1; i<=k; i++) {
a[i-1] = i;
}
j = k-1;
while (j >= 1) {
// submit current results
result.push(a.slice());
if (a[k-1] == n) {
j = j - 1;
} else {
j = k-1;
}
if (j >= 1) {
// make next k-set based on previous one
for (var i=k; i>=j; i--) {
a[i-1] = a[j-1] + i - j + 1;
}
}
}
return result;
}
Note: JavaScript arrays have start index 0 so in code we have -1 correction for array indices (cause set of possible values from 1 to n)