Creating "m x n" Two Dimensional array in javascript - javascript

Would like to create a two dimensional m x n array in javascript, based on the number of columns, that is inputed as an argument in my function, the rows would be created from another argument which would be an array.
What I look to achieve - Desired Result:
var arr = [0,1,2,3,4,5,6,7,8,9]
function TwoDimensionalArray(numRows, numCols) {
//Magic happens here!
}
TwoDimensionalArray(arr, 4);
As you can see the is a 3 x 4 matrix below and a desired result
[[0,1,2,3], [4,5,6,7],[8,9]]
The input size doesn't make the difference, the number of columns is the key factor and the determinant factor.
What I have currently - Not Desired Result:
var arr = [0,1,2,3,4,5,6,7,8,9,10,11,12,13]
function TwoDimensionalArray(numRows, numColumns) {
var twoD = [];
for (var row = 0; row < numRows.length; ++row) {
var cardIndex = numRows[row]
// console.log(numRows[row]);
var columns = [];
for(var j =0; j < numColumns; ++j) {
columns[j] = cardIndex;
}
twoD[cardIndex] = columns;
}
return twoD;
};
var matrixTwoD = TwoDimensionalArray(arr, 4);
console.log(matrixTwoD);
console.log(matrixTwoD[0][0]);
console.log(matrixTwoD[0][1]);
console.log(matrixTwoD[0][2]);
console.log(matrixTwoD[0][3]);
My current code creates an array that repeats each of the elements 4 times each until the number 13 with a column size of 4: [[0,0,0,0], [1,1,1,1]....[13,13,13,13]]
Maybe am doing something wrong in my for loop or not approaching the problem correctly. But anything to point me in the right direction to get the above desire result.
Bouns
Also would anyone also be kinda to point me to additional resources for matrix algebra pertaining to this sort of problem and anything in general that would help for self study.
Thanks a bunch!

Keep it simple, slice the input Array into sections of numCols length
function TwoDimensionalArray(arr, numCols) {
var arr2d = [],
i;
if (numCols) // safety first!
for (i = 0; i < arr.length; i += numCols)
arr2d.push(arr.slice(i, i + numCols));
return arr2d;
}
if (numCols) prevents an infinite loop in the case numCols was not provided or is 0
for (i = 0; i < arr.length; i += numCols) counts up from 0 in numCols, e.g. i = 0, 4, 8, 16, ... until we reach a number greater than arr.length
arr.slice(i, i + numCols) creates a sub-Array of Array starting from (including) index i and ending at (excluding) index i + numCols, i.e. we get a numCols long Array starting with the item at index i of arr
arr2d.push appends a new item to the end of arr2d
Putting all these together, we can see that we are building a new Array arr2d from sections of the Array arr

calculate columns required and then use slice method of array.
start index = (numColumns * i)
end index = numColumns * (i + 1)
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function TwoDimensionalArray(numRows, numColumns) {
var columns = [];
for (var i = 0; i !== Math.ceil(numRows.length / numColumns); i++) {
columns[i] = numRows.slice((numColumns * i), numColumns * (i + 1))
//console.log((numColumns * i) + " " +numColumns * (i + 1))
}
return columns;
};
var matrixTwoD = TwoDimensionalArray(arr, 4);
console.log(matrixTwoD);
console.log(matrixTwoD[0][0]);
console.log(matrixTwoD[0][1]);
console.log(matrixTwoD[0][2]);
console.log(matrixTwoD[0][3]);

Related

Finding the highest divisible sum of elements in an array Javascript

I need to find the highest possible sum of numbers in an array passed to a function that can be divided with no remainder.
I am struggling to think of a way of iterating through an array of elements adding up all the possibilities and dividing by the parameter k which is the number for the division.
I thought of using a for loop and then passing the result to a variable on each iteration.
The part I can't get my head around is how to add all the possible combinations of the numbers in the array. As I can add them sequentially from the start of the array to the last element but not in all combinations such as element at index 0, element at index 3 etc.
I am fairly new to coding, explanations of how you could tackle the iteration challenge I have would be much appreciated.
function luckyCandies(prizes, k) {
let sum = 0;
let remainder = 0;
let maxCandies = 0;
let highestNumber = 0;
prizes.sort(function(a, b) {
return b - a;
});
for (let i = 0; i < prizes.length; i++) {
sum = sum + prizes[i];
}
for (let i = 0; i < prizes.length; i++) {
if (sum % k == 0) {
sum = sum - prizes[i];
}
}
console.log(sum);
return sum;
}
Implemented this solution for your use case based on the answers in this.
In the given link the solutions are for the highest possible sum of numbers given the divisible 3 but it won't be a problem since there is a proper in detailed explanation.
const maxSumDivByNo = (A, no) => {
const K = Array(no).fill().map((v,i) => 0);
for (let x of A) {
let pre = [...K]; // create current from previous 🤔
for (let y of pre)
K[(x + y) % no] = Math.max(K[(x + y) % no], x + y); // add A[i] (ie. x) onto each previous bucket and update each current bucket to max of itself and the current sum (x + y)
}
return K[0]; // max sum of all N items of A which is evenly divisible by no 🎯
};
const A = [1, 2, 3, 4, 5];
const no = 5;
console.log(maxSumDivByNo(A, no)); // --> 15
const A1 = [1, 6, 2, 9, 5];
const no1 = 8
console.log(maxSumDivByNo(A1, no1)); // --> 16

Can someone explain me how does this javascript code works please?

Given a JavaScript function that takes in an array of numbers as the first and the only argument.
The function then removes one element from the array, upon removal, the sum of elements at odd indices is equal to the sum of elements at even indices. The function should count all the possible unique ways in which we can remove one element at a time to achieve balance between odd sum and even sum.
Example var arr = [2, 6, 4, 2];
Then the output should be 2 because, there are two elements 6 and 2 at indices 1 and 3 respectively that makes the combinations table.
When we remove 6 from the array
[2, 4, 2] the sum at odd indexes = sum at even indexes = 4
if we remove 2
[2, 6, 4] the sum at odd indices = sum at even indices = 6
The code below works perfectly. There might be other solutions but I want to understand this one, because I feel there is a concept I have to learn here. Can someone explain the logic of this algorithm please?
const arr = [2, 6, 4, 2];
const check = (arr = []) => {
var oddTotal = 0;
var evenTotal = 0;
var result = 0;
const arraySum = []
for (var i = 0; i < arr.length; ++i) {
if (i % 2 === 0) {
evenTotal += arr[i];
arraySum[i] = evenTotal
}
else {
oddTotal += arr[i];
arraySum[i] = oddTotal
}
}
for (var i = 0; i < arr.length; ++i) {
if (i % 2 === 0) {
if (arraySum[i]*2 - arr[i] + oddTotal === (arraySum[i - 1] || 0)*2 + evenTotal) {
result = result +1
};
} else if (arraySum[i]*2 - arr[i] + evenTotal === (arraySum[i - 1] || 0)*2 + oddTotal) {
result = result +1
}
}
return result;
};

How to remove specific number values in the array javascript [duplicate]

This question already has answers here:
How can I remove a specific item from an array in JavaScript?
(142 answers)
Closed 4 years ago.
So im trying to remove the numbers 1,2,7,14 in the array but i dont know how to remove it. I did not find any solution that is similar to this
function mySelect(){
var prime1 = document.getElementById('input1').value;
var prime2 = document.getElementById('input2').value;
var n = prime1 * prime2;
console.log(n);
var foo = new Array(n);
console.log(foo.length);
var range = [];
for(var i=1;i<foo.length;i++){
range.push(i);
}
console.log(range);
// --------------------------------------------//
var half = Math.floor(n / 2), // Ensures a whole number <= num.
str = '1', // 1 will be a part of every solution.
i, j;
// Determine our increment value for the loop and starting point.
n % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2);
for (i; i <= half; i += j) {
n % i === 0 ? str += ',' + i : false;
}
str += ',' + n; // Always include the original number.
console.log(str);
}
After you pushed the values to the array you can use a filter function, like so:
let nonos = [ 1, 2, 7, 14 ];
range = range.filter((element) => !nonos.includes(element));
This code specifies the values you want removed inside an array and then runs a loop on your original array and checks whether the element you're on is included in your nonos array and if it is, don't include it in your original array, else do.
To remove all instances of the provided numbers from an array:
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function removeNumbers(array, ...numbers) {
numbers.forEach((number) => {
var index = array.indexOf(number);
while(index >= 0) {
array.splice(index, 1);
index = array.indexOf(number);
}
});
}
removeNumbers(array, 3, 2, 5, 7);
console.log(array);
find the index first and then apply splice method.
var array=[1,2,3,4,5,6,7,8,9,10]
console.log(array)
find the index of value you want to delete
let indexa=array.indexOf(2);
apply splice method to delete 1 value from applied index
array.splice(indexa,1);
console.log(array)

Javascript for-loop with certain step

I have an array with 100 elements, I want to take an element from 10th to 15th (10, 11, 12, 13, 14, 15), than from 20th to 25th, than from 30th to 35th, from 40th to 45th and from 50th to 55th, so I always have a gap= 4 and store to a new 2D value. I found out how to store to 2D array, but how could I make this gap?
this is how I could make a chunk of size 6 (because I always need first six element of "decade")
var newArr = [];
while(arr.length) newArr.push(arr.splice(0,6));
or
function splitArray(array, part) {
var tmp = [];
for(var i = 0; i < array.length; i += part) {
tmp.push(array.slice(i, i + part));
}
return tmp;
}
console.log(splitArray(m1, 6));
But first of all I have to make a new array of elements (10-15, 20-25 and so on...). How could I do this?
Your function needs a separate parameter for the stride and the size of each part. It uses the stride when incrementing the for loop variable, and the size when taking the slice.
function splitArray(array, stride, size) {
var tmp = [];
for(var i = 0; i < array.length; i += stride) {
tmp.push(array.slice(i, i + size));
}
return tmp;
}
var m1 = [];
for (var i = 0; i < 100; i++) {
m1.push(i);
}
console.log(splitArray(m1, 10, 6));
A generator function removes the need to store intermediate results. Introducing an offset argument allows you to skip the first five values 0, 1, 2, 3, 4, 5:
function* splitArray(array, stride, size, offset = 0) {
for (let i = offset; i < array.length; i += stride) {
yield array.slice(i, i + size);
}
}
// Example:
const array = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25];
console.log(...splitArray(array, 10, 6, 10));
Apart from those particularities, this implementation is identical to Barmar's answer.

Find the smallest sum of all indexes of unique number pairs summing to a given number

I want to loop through an array and then add each value to each other (except itself + itself) and if the sum of the two values that were looped through equals the second argument in my function, and the pair of values hasn't been encountered before, then remember their indices and, at the end, return the full sum of all remembered indices.
In other words, the problem statement is: given an array A of integers and a second value s that is a desired sum, find all pairs of values from array A at indexes i, j such that i < j and A[i] + A[j] = s, and return the sum of all indexes of these pairs, with the following restriction:
don't reuse value pairs, i.e. if two index pairs i, j and k, l satisfying the above conditions are found and if A[i] == A[k] and A[j] == A[l] or A[i] == A[l] and A[j] == A[k], then ignore the pair with the higher index sum.
Example
For example, functionName([1, 4, 2, 3, 0, 5], 7) should return 11 because values 4, 2, 3 and 5 can be paired with each other to equal 7 and the 11 comes from adding the indices of them to get to 11 where:
4 + 3 = 7
5 + 2 = 7
4 [index: 1]
2 [index: 2]
3 [index: 3]
5 [index: 5]
1 + 2 + 3 + 5 = 11
Example #2
functionName([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0 and the second 1
1 + 3 = 4
1 [index: 0]
3 [index: 1]
0 + 1 = 1
This is what I have so far:
function functionName(arr, arg) {
var newArr = [];
for(var i = 0; i < arr.length; i++){
for(var j = i + 1; j < arr.length; j++) {
if((arr[i] + arr[j]) === arg ) {
newArr.push(i , j);
}
}
}
if(newArr.length === 0) {
return console.log(0);
}
return console.log(newArr.reduce(function(a,b){return a + b}));
}
functionName([1, 4, 2, 3, 0, 5], 7);
The problem I have is that it all works but I have the issue that once it finds a pair that equals the second argument, then it's not supposed to use the same value pairs again but mine does, e.g.:
if the array is [1,1,1] and the second argument is 2, the loop will go through and find the answer but it continues to search after it finds the sum and I only want it to use the pair [1, 1] once, so if it finds a pair like this at indexes [0, 1] then it should not include any other pair that contains the value 1.
I was thinking that i could remove the rest of the values that are the same if more than 2 are found using filter leaving me with only 2 of the same value if there is in an array thus not having to worry about the loop finding a 1 + 1 twice but is this the best way to go about doing it?
I'm still new to this but looking forward to your comments
PS I'm planning on doing this using pure JavaScript and no libraries
Link to a JS fiddle that might make things easier to see what I have.
https://jsfiddle.net/ToreanJoel/xmumv3qt/
This is more complicated than it initially looks. In fact, making a loop inside a loop causes the algorithm to have quadratic time complexity with regard to the size of the array. In other words, for large arrays of numbers, it will take a very long time to complete.
Another way to handle this problem is to notice that you actually have to use each unique value in the array only once (or twice, if s is even and you have two s/2 values somewhere in the array). Otherwise, you would have non-unique pairs. This works because if you need pairs of numbers x and y such that x + y = s, if you know x, then y is determined -- it must be equal s - x.
So you can actually solve the problem in linear time complexity (to be fair, it's sometimes n*log(n) if all values in A are unique, because we have to sort them once).
The steps of the algorithm are as follows:
Make a map whose keys are values in array A, and values are sorted lists of indexes these values appear at in A.
Move through all unique values in A (you collected them when you solved step 1) in ascending order. For each such value:
Assume it's the lower value of the searched pair of values.
Calculate the higher value (it's equal to s - lower)
Check if the higher value also existed in A (you're doing it in constant time thanks to the map created in step 1).
If it does, add the lowest indexes of both the lower and the higher value to the result.
Return the result.
Here's the full code:
function findSumOfUniquePairs(numbers, sum) {
// First, make a map from values to lists of indexes with this value:
var indexesByValue = {},
values = [];
numbers.forEach(function (value, index) {
var indexes = indexesByValue[value];
if (!indexes) {
indexes = indexesByValue[value] = [];
values.push(value);
}
indexes.push(index);
});
values.sort();
var result = 0;
for (var i = 0, maxI = values.length; i < maxI; ++i) {
var lowerValue = values[i],
higherValue = sum - lowerValue;
if (lowerValue > higherValue) {
// We don't have to check symmetrical situations, so let's quit early:
break;
}
var lowerValueIndexes = indexesByValue[lowerValue];
if (lowerValue === higherValue) {
if (lowerValueIndexes.length >= 2) {
result += lowerValueIndexes[0] + lowerValueIndexes[1];
}
} else {
var higherValueIndexes = indexesByValue[higherValue];
if (higherValueIndexes) {
result += lowerValueIndexes[0] + higherValueIndexes[0];
}
}
}
return result;
}
document.write(findSumOfUniquePairs([1, 4, 2, 3, 0, 5], 7) + '<br>'); // 11;
document.write(findSumOfUniquePairs([1, 3, 2, 4], 4) + '<br>'); // 1
document.write(findSumOfUniquePairs([1, 1, 1], 2) + '<br>'); // 1
document.write(findSumOfUniquePairs([1, 1, 1, 1], 2) + '<br>'); // 1
document.write(findSumOfUniquePairs([1, 2, 3, 1, 2, 3, 1], 4) + '<br>'); // 7
document.write(findSumOfUniquePairs([5, 5, 1, 1, 1], 6) + '<br>'); // 2
document.write(findSumOfUniquePairs([0, 5, 0, 5, 1, 1, 1], 6) + '<br>'); // 5
This works, but it mucks up the initial array.
function functionName(arr, arg) {
var newArr = [];
for(var i = 0; i < arr.length; i++){
for(var j = i + 1; j < arr.length; j++) {
if((arr[i] + arr[j]) === arg ) {
newArr.push(i , j);
arr[i] = null;
arr[j] = null;
}
}
}
if(newArr.length === 0) {
return console.log(0);
}
return console.log(newArr.reduce(function(a,b){return a + b}));
}
Solution with loops with restart, if a sum is found. the found summands are stored in usedNumbers and later sorted and used to get the index for summing the index.
The sorting and the last index provides the correct start position for the Array.prototype.indexOf.
Edit:
what about [1,1,1,1], 2 ... should that be 6 or 1? – Jaromanda X 21
#JaromandaX that should be 1, after the pair is found with the values then it shouldn't look for a pair with the same values again – Torean
This version takes care of the requirement.
function f(array, sum) {
var arrayCopy = array.slice(0),
usedNumbers = [],
index = 0,
indexA = 0,
indexB,
a, b;
while (indexA < arrayCopy.length) {
indexB = indexA + 1;
while (indexB < arrayCopy.length) {
a = arrayCopy[indexA];
b = arrayCopy[indexB];
if (a + b === sum) {
usedNumbers.push(a, b);
arrayCopy = arrayCopy.filter(function (i) { return a !== i && b !== i; });
indexA--; // correction to keep the index
break;
}
indexB++;
}
indexA++;
}
return usedNumbers.sort().reduce(function (r, a, i) {
index = array.indexOf(a, i === 0 || a !== usedNumbers[i - 1] ? 0 : index + 1);
return r + index;
}, 0);
}
document.write(f([1, 4, 2, 3, 0, 5], 7) + '<br>'); // 11
document.write(f([1, 1, 1], 2) + '<br>'); // 1
document.write(f([5, 5, 1, 1, 1], 6) + '<br>'); // 2
document.write(f([0, 5, 0, 5, 1, 1, 1], 6) + '<br>'); // 5
document.write(f([1, 1, 1, 1], 2) + '<br>'); // 1
The solution below is very compact. It avoids unnecessary checks and loops only through the relevant elements. You can check the working codepen here:
http://codepen.io/PiotrBerebecki/pen/RRGaBZ.
function pairwise(arr, arg) {
var sum = 0;
for (var i=0; i<arr.length-1; i++) {
for (var j=i+1; j<arr.length; j++) {
if (arr[i] <= arg && arr[j] <= arg && arr[i] + arr[j] == arg) {
sum += i+j;
arr[i] = arr[j] = NaN;
}
}
}
return sum;
}
console.log( pairwise([1, 1, 0, 2], 2) ) // should return 6
Under the hood:
Start looping from the element with index (i) = 0.
Add a second loop only for the elements which are later in the array. Their index j is always higher than i as we are adding 1 to i.
If both elements (numbers) are less than or equal to to the arg, check if their sum equals to the arg. This avoids checking the sum if either of the numbers are greater than the arg.
If the pair has been found then change their values to NaN to avoid further checks and duplication.
This solution should have a time complexity of 0(n) or linear
Much faster than two nested for-loops. This function will give you the two indices that add up to the target number. It can easily be modified to solve any other configuration of this problem.
var twoSum = function(nums, target) {
const hash = {}
for(let i = 0; i < nums.length; i++) {
hash[nums[i]] = i
}
for(let j = 0; j < nums.length; j++) {
let numToFind = target - nums[j]
if(numToFind in hash && hash[numToFind] !== j) {
return [hash[numToFind], j]
}
}
return false
};
console.log(twoSum([1,2,3,5,7], 5))
In Python:
def twoSum(self, nums: List[int], target: int) -> List[int]:
myMap = {}
for i in range(len(nums)):
myMap[nums[i]] = i
for j in range(len(nums)):
numToFind = target - nums[j]
if numToFind in myMap and myMap[numToFind] != j:
return [myMap[numToFind], j]
print(twoSum([1,2,3,5,7], 5))
In Java:
import java.util.*;
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for(Integer i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for(Integer j = 0; j < nums.length; j++) {
Integer numToFind = target - nums[j];
Integer myInt = map.get(numToFind);
if(map.containsKey(numToFind) && myInt != j) {
return new int[] {myInt , j};
}
}
return new int[] {0, 0};
}
}
System.out.println(twoSum([1,2,3,5,7], 5))

Categories