distribution of values from 2 arrays in javascript - javascript

I'm trying to find a way to distribute 2 arrays equally for example I got
let a = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
let b = [0,0,0,0]
function distrubute(a, b){
//I need help with this function
return ?
}
let distributed = distribute()
console.log(distributed)
// [0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1]
// this one has to be true:
console.log(distributed.length === a.length)

make sure the first parameter is the bigger array
calculate ratio between two arrays
iterate them both, if the iteration index is divided by (ratio + 1) with remainder -> pick a value from the bigger array, else -> pick a value from the smaller array.
Original question answer:
const a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
const b = [0, 0, 0, 0]
function distrubute(a, b) {
if (a.length < b.length) return distribute(b, a);
const distributed = [];
const ratio = a.length / b.length;
let iA = 0,
iB = 0;
while (iA + iB < a.length) {
distributed.push((iA + iB) % (ratio + 1) > 0 ? a[iA++] : b[iB++]);
}
return distributed;
}
const distributed = distrubute(a, b);
console.log(distributed);
Edited question answer:
const a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
const b = [0, 0, 0, 0]
function distrubute(a, b) {
if (a.length < b.length) return distribute(b, a);
const distributed = [];
const ratio = a.length / b.length;
let iA = 0,
iB = 0;
while (iA + iB < a.length + b.length) {
distributed.push((iA + iB) % (ratio + 1) > 0 ? a[iA++] : b[iB++]);
}
return distributed;
}
const distributed = distrubute(a, b);
console.log(distributed);

May another short way
function distribute(a, b) {
const distance = a.length / b.length + 1;
return a.map((val, index) => {
if (index % distance === 0) { return b[index / distance]; }
else { return val; }
});
}
// 0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0
function distribute(a, b) {
const distance = a.length / b.length;
return a.flatMap((val, index) => {
if (index % distance === 0) { return [b[index / distance], val]; }
else { return val; }
});
}
// 0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1

Related

trying to find element of array from which sum of left side of array is equal to sum of right side of array in JavaScript

I am trying to find element of array from which sum of left side of array is equal to sum of right side of array in JavaScript
I am using:
function findEvenIndex(arr)
{
//Code goes here!
let num = 0;
function check(i){
console.log(arr);
console.log(num)
let arrPart1 = arr.slice(0,i).reduce(((a,b)=>a+b),0);
console.log(arrPart1)
let arrPart2 = arr.slice(i+1,arr.length).reduce(((c,d)=>c+d),0);
console.log(arrPart2)
if(arrPart2 === 0){
return -1
}
else if(arrPart1 !== arrPart2){
num++;
check(num);
}
}
return check(num);
}
For array:
[1,100,50,-51,1,1]
Getting:
[ 1, 100, 50, -51, 1, 1 ]
0
0
101
[ 1, 100, 50, -51, 1, 1 ]
1
1
1
Error:
The array was: [1,100,50,-51,1,1]
: expected undefined to equal 1
I'd recommend abandoning the recursive solution and opting for an iterative one - in this situation, it's easier to debug. I've written a function that is easy to understand and can solve your problem here:
function findEvenIndex(arr)
{
for(let i = 0; i < arr.length; i++) {
let leftTotal = arr.slice(0, i).reduce((t, v) => t + v, 0);
let rightTotal = arr.slice(i + 1).reduce((t, v) => t + v, 0);
if (leftTotal === rightTotal) {
return i;
}
}
return -1;
}
First check if the array length is an even number
if (array.length % 2 === 1) {
return false;
}
Slice the array in half and reverse the 2nd half
let half = (array.length / 2);
let sub1 = array.slice(0, half);
let sub2 = array.slice(-half).reverse();
Then filter both and return matches
return sub1.filter((num, idx) => num === sub2[idx]);
const array1 = [1, 100, 50, -51, 1, 1];
const array2 = [5, 62, 8, 0, 0, 15, 62, -5];
const array3 = [0, 1, 0];
const mirroredValues = array => {
let half;
if (array.length % 2 === 1) {
return false;
} else {
half = (array.length / 2);
}
let sub1 = array.slice(0, half);
let sub2 = array.slice(-half).reverse();
return sub1.filter((num, idx) => num === sub2[idx]);
};
console.log(mirroredValues(array1));
console.log(mirroredValues(array2));
console.log(mirroredValues(array3));
I would do it like this:
const findElementIndex = (array, index = 0) => {
let arr_part_1 = array.slice(0, index).reduce(((a, b) => a + b), 0);
let arr_part_2 = array.slice(index + 1, array.length).reduce(((a, b) => a + b), 0);
return arr_part_1 === arr_part_2 ? index : index === array.length ? -1 : findElementIndex(array, index + 1);
};
console.log('Example 1: ', findElementIndex([1, 1, 10, 2]));
console.log('Example 2: ', findElementIndex([1, 1, 1, 10, 2]));
console.log('Example 3: ', findElementIndex([100, 1, 100]));
That one could be better from performance point of view (reduce only once)
function inTheMiddle(arr) {
let rightSum = arr.slice(2).reduce((total, item) => total + item, 0);
let leftSum = arr[0];
console.log(leftSum, rightSum);
for (let i = 2; i < arr.length; i++) {
if (leftSum === rightSum) {
return i-1;
}
leftSum += arr[i-1];
rightSum -= arr[i];
console.log(leftSum, rightSum);
}
return -1;
}
console.log("In the middle:", inTheMiddle([1,100,50,-51,1,1]))

Regarding quick selection function

first of all thank you for help!
My issue is I'm trying to find kth largest but some of testcases are failing. If argument is [1,1,1] and k = 1. It will hit base case which is undefined. I'm not sure why it's hitting base case. Again, thank you so much! let me know if you guys need more info!
function kth_largest_in_an_array(numbers, k) {
return quickSort3(numbers, k, 0, numbers.length-1);
}
const quickSort3 = (numbers, k, start, end) => {
if (start >= end) {
console.log('base case')
return;
}
//remember random index
console.log('before: ', numbers)
let randomIdx = Math.floor(start + Math.random() * (end - start));
let partitionedIdx = partition(numbers, start, end, randomIdx);
console.log('randomIdx: ',randomIdx)
console.log('partitionedIdx: ',partitionedIdx)
console.log('start: ', start, 'end: ', end)
console.log(numbers.slice(start, end+1))
console.log(numbers)
console.log('number.length: ',numbers.length)
//numbers.length = 5, 5-2 == 3
// console.log('numbers.length - k: ', numbers.length - k)
if (numbers.length - k === partitionedIdx) {
console.log('imin: ', numbers[partitionedIdx])
return numbers[partitionedIdx];
}
else if (partitionedIdx < numbers.length - k) {
return quickSort3(numbers, k, partitionedIdx+1, end);
}
else {
return quickSort3(numbers, k, start, partitionedIdx-1)
}
}
const partition = (numbers, start, end, randomIdx) => {
[numbers[start], numbers[randomIdx]] = [numbers[randomIdx], numbers[start]];
let pivot = numbers[start];
let i = start;
for (let j = i+1; j<=end; j++) {
if (pivot > numbers[j]) {
i++
[numbers[i], numbers[j]] = [numbers[j], numbers[i]];
}
}
[numbers[start], numbers[i]] = [numbers[i], numbers[start]];
return i;
}
console.log(kth_largest_in_an_array([1,1,1], 1))
// console.log(kth_largest_in_an_array([4, 1, 2, 2, 3, 4], 2))
// console.log(kth_largest_in_an_array([5, 1, 10, 3, 2], 2))
Are you looking for something like this?
const t = (arr, kth) => {
const a = arr.sort((a, b) => b - a);
return a[kth];
}
console.log(t([1,1,1], 1))
console.log(t([4, 1, 2, 2, 3, 4], 2))
console.log(t([5, 1, 10, 3, 2], 2))

I have completed this code in hackerrank for second largest no. in javascript but test cases are showing wrong. below is the code

javscript second largest no. code
please help me solve this program
function getSecondLargest(nums) {
// Complete the function
nums.sort();
//console.log("sorted array", nums);
let largest_no = nums[nums.length-1];
let final_array = nums.filter(x => x != largest_no);
let second_largest_no = final_array[final_array.length-1]
console.log("filtered array", final_array);
return second_largest_no;
}
getSecondLargest([2, 2, 1, 2, 5, 1, 5, 3, 4, 6, 6 , 6 , 5 , 5]);
If they are looking for "5" as a 2nd largest number by ignoring the duplicates. Then below code can be used to find 2nd largest value.
"Default_Min" can be set as per your requirements.
This algorithm will have O(n) time complexity. which is be better than using sorting and filtering.
function SencondLargest(nums)
{
let max_1;
let max_2;
let Default_Min = 0;
if (nums.length < 2)
{
console.log(" Invalid Input ");
return;
}
max_1 = max_2 = Default_Min;
for(let i=0; i<nums.length; i++)
{
if (nums[i] > max_1)
{
max_2 = max_1;
max_1 = nums[i];
}
else if (nums[i] > max_2 && nums[i] != max_1)
max_2 = nums[i];
}
if (max_2 == Default_Min)
console.log("There is no second largest"+ " element\n");
else
console.log("The second largest element"+ " is "+ max_2);
}
var x = [2, 2, 1, 2, 5, 1, 5, 3, 4, 6, 6 , 6 , 5 , 5];
SencondLargest(x);
Try to use reduce method to have O(N) complexity. So we can use reduce method to iterate through array and have values such as largeValue: 0, largerValue: 0, largestValue: 0 as accumulator of reduce method:
const obj = arr.reduce((a, c, i) => {
a[c] = a[c] || {c};
if (i === 0) {
a.largeValue = c;
a.largerValue = c;
a.largestValue = c;
}
else {
if (c > a.largeValue && c < a.largerValue && c > a.largestValue) {
a.largeValue = c;
}
else if (c > a.largeValue && c > a.largerValue) {
if (a.largerValue == a.largestValue) {
a.largerValue = c;
}
else {
a.largestValue = c;
}
}
}
return a;
},{ largeValue: 0, largerValue: 0, largestValue: 0 });
An example:
let arr = [2, 2, 1, 2, 5, 1, 5, 3, 4, 6, 6 , 6 , 5 , 5];
const obj = arr.reduce((a, c, i) => {
a[c] = a[c] || {c};
if (i === 0) {
a.largeValue = c;
a.largerValue = c;
a.largestValue = c;
}
else {
if (c > a.largeValue && c < a.largerValue && c > a.largestValue) {
a.largeValue = c;
}
else if (c > a.largeValue && c > a.largerValue) {
if (a.largerValue == a.largestValue) {
a.largerValue = c;
}
else {
a.largestValue = c;
}
}
}
return a;
},{ largeValue: 0, largerValue: 0, largestValue: 0 });
console.log(obj.largerValue);

My loop is running twice and not giving the right answer any solution for this [duplicate]

This question already has an answer here:
Linear time algorithm for Maximum contiguous sub-array sum
(1 answer)
Closed 3 years ago.
** The maximum sum subarray problem consists in finding the maximum sum
of a contiguous subsequence in an array or list of integers:
maxSequence([-2, 1, -3, 4, -1, 2, 1, -5, 4]) // should be 6: [4, -1,
2, 1] Easy case is when the list is made up of only positive numbers
and the maximum sum is the sum of the whole array. If the list is made
up of only negative numbers, return 0 instead.
Empty list is considered to have zero greatest sum. Note that the
empty list or array is also a valid sublist/subarray.**
var maxSequence = function(arr) {
// ...
let max = 0;
const sorted = arr.sort((a, b) => {
return a - b;
});
if (arr.length == 0) {
return 0;
} else if (sorted[sorted.length - 1] >= 0 && sorted[0] >= 0) {
let max = 0;
for (let i = 0; i < sorted.length; i++) {
max += sorted[i];
}
return max;
} else if (sorted[0] < 0 && sorted[sorted.length - 1] < 0) {
console.log(0);
} else {
let halfLength = Math.floor(arr.length / 2);
let pivot = 0;
let sequence = 0;
let next = 1;
while (pivot <= arr.length - 1) {
if (arr[next] <= halfLength) {
sequence += arr[next];
next += 1;
} else {
sequence = 0;
halfLength += 1;
pivot += 1;
next = pivot + 1;
}
if (pivot == arr.length - 2) {
sequence += arr[next];
next += 1;
break;
}
if (sequence >= max) {
max = sequence;
}
}
console.log("the answer", max);
}
};
maxSequence([-2, 1, -3, 4, -1, 2, 1, -5, 4]); //, 6)
**The code return 12 instead of 6 any solution i have been trying for an hour now **
You could just test it for all combinations and see which one give you the best score.
function maxSequence(data) {
let result = {
value: null,
seq: null
}
let check = {
pos: true,
neg: true
}
data.forEach(e => {
if (e > 0) check.neg = false;
if (e < 0) check.pos = false;
})
if (check.pos) {
return sum(data)
} else if (check.neg) {
return 0;
}
function sum(seq) {
return seq.reduce((r, e) => r + e, 0)
}
for (let i = 0; i < data.length; i++) {
for (let j = i; j < data.length; j++) {
const seq = data.slice(i, j + 1);
const seqSum = sum(seq);
if (result.value === null || seqSum > result.value) {
result.value = seqSum;
result.seq = seq;
}
}
}
return result;
}
console.log(maxSequence([-2, 1, -3, 4, -1, 2, 1, -5, 4]))
console.log(maxSequence([1, 5, 9, 1]))
console.log(maxSequence([-1, -2, -3, -4]))

Maximum Length of Repeated Subarray (leetcode)

I'm looking at this leetcode question, and am having an issue completing the naive approach. I was able to come to an optimal solution here. But I'm not sure what's wrong with my naive attempt.
The question is as follows:
Given two integer arrays A and B, return the maximum length of an
subarray that appears in both arrays.
Example:
Input: A: [1,2,3,2,1] B: [3,2,1,4,7]
Output: 3
Explanation: The repeated subarray with maximum length is [3, 2, 1].
Here is my current code:
var findLength = function(a, b) {
if (a.length === 0 || b.length === 0) {
return 0;
}
let aWithoutFinalNumber = a.slice(0, a.length - 1);
let bWithoutFinalNumber = b.slice(0, b.length - 1);
let aFinalNumber = a[a.length - 1];
let bFinalNumber = b[b.length - 1];
// matching numbers
if(aFinalNumber === bFinalNumber) {
return 1 + findLength(aWithoutFinalNumber, bWithoutFinalNumber);
} else { // mismatch. Compete to find the maximum length.
return Math.max(findLength(a, bWithoutFinalNumber), findLength(aWithoutFinalNumber, b));
}
};
My solution passes several test cases, but fails on cases like a: [0,1,1,1,1] b: [1,0,1,0,1]. Any insight on my mistake would be appreciated!
The problem comes from the way you calculate the max length when the last elements match. here is a minimal example:
var findLength = function(a, b) {
if (a.length === 0 || b.length === 0) {
return 0;
}
let aWithoutFinalNumber = a.slice(0, a.length - 1);
let bWithoutFinalNumber = b.slice(0, b.length - 1);
let aFinalNumber = a[a.length - 1];
let bFinalNumber = b[b.length - 1];
// matching numbers
if(aFinalNumber === bFinalNumber) {
return 1 + findLength(aWithoutFinalNumber, bWithoutFinalNumber); //< -- problem here
} else { // mismatch. Compete to find the maximum length.
return Math.max(findLength(a, bWithoutFinalNumber), findLength(aWithoutFinalNumber, b));
}
};
console.log(findLength([1, 0, 2, 1], [1, 0, 3, 1]));
If there is any match you add 1 to the max length but that's not necessarily true if there is a mismatch later. Here is a shortened version what happens with illustration for easier understanding:
[1, 0, 2, 1]
^-------|
[1, 0, 3, 1] | -- match, max length +1
^-------|
______
[1, 0, 2, 1]
^----------|
[1, 0, 3, 1] | -- mismatch, max length +0
^----------|
______
[1, 0, 2, 1]
^-------------|
[1, 0, 3, 1] | -- match, max length +1
^-------------|
______
[1, 0, 2, 1]
^----------------|
[1, 0, 3, 1] | -- match, max length +1
^----------------|
When you total all the matches, you get 3 however, the count should have been reset when there was a mismatch.
One simple change that can be done to the algorithm to avoid this problem is to pass the current count as an argument to the function. This way, you can control when the count needs to be reset:
var findLength = function(a, b, maxSoFar = 0) { //<-- default count of zero
if (a.length === 0 || b.length === 0) {
return maxSoFar; //<-- return the count
}
let aWithoutFinalNumber = a.slice(0, a.length - 1);
let bWithoutFinalNumber = b.slice(0, b.length - 1);
let aFinalNumber = a[a.length - 1];
let bFinalNumber = b[b.length - 1];
// matching numbers
if(aFinalNumber === bFinalNumber) {
const newMax = maxSoFar + 1; //<-- increment the count
return Math.max(newMax, findLength(aWithoutFinalNumber, bWithoutFinalNumber, newMax)); //<-- return the newMax in case the next is a mismatch
} else { // mismatch. Compete to find the maximum length.
return Math.max(findLength(a, bWithoutFinalNumber), findLength(aWithoutFinalNumber, b)); //<-- reset the count
}
};
console.log(findLength([1, 0, 2, 1], [1, 0, 3, 1]));
console.log(findLength([1, 2, 3, 2, 1], [3, 2, 1, 4, 7]));
console.log(findLength([0, 1, 1, 1, 1], [1, 0, 1, 0, 1]));
You could use nested loop and when same element occur in both arrays you could start incrementing both of those indexes until elements in both arrays are the same. The result that gives you the largest set of elements will be the returned result.
function maxSub(a, b) {
let result = null;
function findAll(i, j) {
const res = [];
if (a[i] !== b[j] || a[i] == undefined || b[j] == undefined) {
return res;
}
return res.concat(a[i], ...findAll(i + 1, j + 1))
}
a.forEach((e, i) => {
b.forEach((c, j) => {
if (e == c) {
const sub = findAll(i, j);
if (!result || sub.length > result.length) {
result = sub
}
}
})
})
return result;
}
console.log(maxSub([0, 1, 1, 1, 1], [1, 0, 1, 0, 1]))
console.log(maxSub([1, 2, 3, 2, 1], [3, 2, 1, 4, 7]))
you can use dp with a table as well. i tried the other code, and it gave errors in cases like: [0,0,0,0,1,0,0] and [0,0,0,0,0,1,0].
Here is a python code for the same.
def findLength(a, b):
if len(a)==0 or len(b)==0:
return 0
n=len(a)
m=len(b)
dp=[[0 for _ in range(n+1)] for _ in range(m+1)]
maxSoFar=0
for i in range(1,m+1):
for j in range(1,n+1):
if a[j-1]==b[i-1]:
dp[i][j]=dp[i-1][j-1]+1
maxSoFar=max(maxSoFar,dp[i][j])
else:
dp[i][j]=0
return maxSoFar

Categories

Resources