Find the number of adjacent element trios with given sum - javascript

I'm trying to find the number of adjacent element trios with a given sum.
Example:
Inputs arr = [1,2,3,12,1,4,9,6] sum = 6
Output = 2
([1,2,3,12,1,4,1,6])
My Code:
function getCount(arr, sum) {
var count = 0;
var indexes = [];
for (var i = 0; i < arr.length-2; i++) {
for (var j = i + 1; j < arr.length-1; j++) {
for (var k = j + 1; k < arr.length; k++){
if ((arr[i] + arr[j] + arr[k] == sum) && indexes.includes(i) && indexes.includes(j)) {
count++;
}
}
}
}
return count;
}
getCount([1,2,3,12,3,4,9,6],19);
But this is not work for adjacent elements.

I would just use a single loop/pass here:
function getCount(arr, sum) {
if (arr.length < 3) return 0;
var count = 0;
var first = arr[0];
var second = arr[1];
var third;
for (var i=2; i < arr.length; i++) {
third = arr[i];
var currSum = first + second + third;
if (currSum == sum) ++count;
first = second;
second = third;
}
return count;
}
console.log(getCount([], 3));
console.log(getCount([1, 2], 3));
console.log(getCount([1, 2, 3], 3));
console.log(getCount([1, 2, 3], 6));
console.log(getCount([1,2,3,12,3,4,9,6], 19));
The strategy here is to just walk down the input array once, keeping track of the current, previous, and previous previous values at each step. Then, we compute the sum of those three values, and compare against the input target sum.

Related

JS: Given an array, find element pairs whose sum equal the target value

Yes, as the title suggests
Given an array arr, find element pairs whose sum equal the second argument arg and return the sum of their indices.
What I have done so far
function pairwise(arr, arg) {
if (arr.length === 0) return 0
let res = [];
let indexes = [];
let indexArr = []
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arg === arr[i] + arr[j] && !indexes.includes(i) && !indexes.includes(j)) {
res.push([arr[i], arr[j]]);
indexes.push(i);
indexes.push(j);
}
}
}
console.log(res)
for (let i = 0; i < res.length; i++) {
for (let j = 0; j < res[i].length; j++) {
indexArr.push(arr.indexOf(res[i][j]))
}
}
return indexArr.reduce((curr, prev) => curr + prev)
}
pairwise([1, 1, 1], 2);
I am doing this in Freecodecamp. It passes some test but fails the following tests:
pairwise([1, 1, 1], 2) should return 1. (above code returns 0)
pairwise([0, 0, 0, 0, 1, 1], 1) should return 10. (above code returns 8)
I think I am doing wrong in the indexOf part. How to solve this?

Find the number of subarrays in an array which has the given sum

Here is the problem: Find the number of subarrays in an array, which has the given sum.
this program enter 2 parameters number array and sum.
for example:
subArrayCnt([1,2,3,2,1,8,-3],5)
and the output should be number of subarrays accoding to given sum.
(output should be 3 for above example {2,3}, {3,2}, {8,-3} (number of subarrays))
I tried to do that but there is a problem with it isn't fulfilling the requirment of "The answer should be valid for any given input"
Here is my code:
function subArrayCnt(arr, sum) {
for (var i = 0; i < arr.length; i++) {
var str = [];
var csum= 0;
var output = 0;
for (var j = i; j < arr.length; j++) {
csum+= arr[j];
str.push(arr[j]);
if (csum== sum) {
return(str[i]);
}
}
}
}
console.log(subArrayCnt([1,2,3,2,1,8,-3],5));
this program provide number of subarrays but it isn't fulfilling the requirment of "The answer should be valid for any given input" where should be corrected? any suggetions please.
The other answers seem to be ignoring the fact that the sum can be obtained from any number of elements of the array. Recursion is the best approach here.
function subArrayCnt(arr, sum){
return subArrayRecurse(arr, sum, 0, [], 0)
}
function subArrayRecurse(arr, sum, currentSum, curArray, i){
var count = 0;
//check the current index
var newSum = currentSum + arr[i];
var newSubArray = curArray.concat([arr[i]]);
if(newSum == sum) {
console.log('found another: ' + newSubArray);
count++;
}
if(i + 1 < arr.length) {
//try including the current in further sums
count += subArrayRecurse(arr, sum, newSum, newSubArray, i + 1);
//try not including the current in further sums
count += subArrayRecurse(arr, sum, currentSum, curArray, i + 1);
}
return count;
}
console.log(subArrayCnt([1,2,3,2,1,8,-3],5));
// 8
The 8 combos from the above example are:
1,2,3,2,-3
1,2,2
1,3,1
2,3
2,3,2,1,-3
2,2,1
3,2
8,-3
From your example, I assumed that the sum of two consecutive elements should be the sum to qualify.
function subArrayCnt(arr, sum) {
let outputArr = [];
for(var i=0; i<arr.length; i++){
if(arr[i]+arr[i+1]==sum){
let obj = {l:arr[i],r:arr[i+1]};
outputArr.push(obj);
}
};
return outputArr.length;
};
Try this approach:
function subArrayCnt(arr, sum){
var count = 0;
for(var i = 0; i < arr.length-1; i++){
for(var n = i+1; n < arr.length; n++){
if(arr[i] + arr[n] == sum){
count++;
}
}
}
return count;
}
console.log(subArrayCnt([1,2,3,2,1,8,-3],5));
// 3
You can do that using nested loop. This will get all the possible adjacent sums and then you can compare that sum with the given sum and increase count.
function func(arr,sum){
if(!Array.isArray(arr)) return 0;
let count = 0;
let cur = 0;
for(let i = 0;i<arr.length-1;i++){
cur = arr[i];
for(let j = i+1;j<arr.length;j++){
cur += arr[j];
if(cur === sum){
count++;
break;
}
if(cur > sum) break;
}
}
return count+'';
}
console.log(func([1,2,3,2,1,8,-3],5)) //3
console.log(func([1,2,3,4],10)) //1
Try this:
<script>
function subArray(arr,sum)
{
var subArray=new Array();
count=0;
for(var i=0;i<arr.length;i++)
{
if(arr[i]+arr[i+1]==sum)
{
subArray[count]=[arr[i],arr[i+1]]
count++;
}
}
return subArray;
}
console.log(subArray([1,2,3,2,1,8,-3],5));
</script>
Try this:
I wrote this function. It fulfill the requirement of "The answer should be valid for any given input".
function getSubArrayCount(arr, sum){
if(!Array.isArray(arr)) return 0;
var len = arr.length;
var count = 0;
for(var i = 0; i < len; i++){
var n = 0;
for(var j = i; j < len; j++){
n += arr[j];
if(n === sum) {
count++;
break;
}
}
}
return count;
}
getSubArrayCount([1,2,3,2,1,8,-3],5);

Loop trough array and sum the length

EDITED:
Can someone help me with the problem below further. I have a class and an array inside the class. I want now use a for loop to sum the length of the previous array length, but for each iteration. If i == 1 I want sum the length of arr[0].x.length, If i == 2 I want sum the length of arr[0].x.length+arr[1].x.length, ect. It will be a lot of code to check each iteration.
Is there a simple way to do this? Instead allways use a new line like
if (i == 1) n = n + arr[i-1].x.length;
if (i == 2) n = n + arr[i-1].x.length+arr[i-2].x.length;
if (i == 3) n = n + arr[i-1].x.length+arr[i-2].x.length+arr[i-3].x.length;
function Class() {
var x = [];
}
for (var i = 0; i < 9; i++) {
arr[i] = new Class();
}
I add 4 items to each object.
arr[0].x.push(...)
arr[0].x.push(...)
...
arr[1].x.push(...)
arr[1].x.push(...)
...
var n = 0;
for (var i = 0; i < arr.length; i++) {
if (i == 1) {
n = n + arr[i-1].x.length;
} else if (i == 2) {
n = n + arr[i-1].x.length+arr[i-2].x.length;
} else if (i == 3) {
n = n + arr[i-1].x.length+arr[i-2].x.length+arr[i-3].x.length;
}
// ect.
}
You could use reduce to get a total of all the lengths of your sub-arrays. For example:
const arrs = [[1, 2, 3], [4, 5, 6]];
const sum = arrs.reduce((acc, arr) => acc += arr.length, 0);
console.log(sum);
// 6
Just nest the loop two times: go over the indexes once then go up to that index from 0 in an inner loop:
for (var i = 0; i < arr1.length; i++) {
for(var j = 0; j <= i; j++) {
n = n + arr1[j].length;
}
}
Edit: benvc's answer is what you are looking for if you want to use reduce.
var arr = [[1,2,3], [4,5,6], [7]];
var n = 0;
for (var i = 0; i < arr.length; i++){
n += arr[i].length;
}
console.log(n);

JavaScript - find the same first element using for loop

I've got to create var with few elements:
var arrNum = [4,7,5,3,4,5,6,7,8,10]
I need to find first number that is the same in array using for loop. So it will be "4" and "4"
I need to create var sameIndex and adjust the same number to sameIndex and print after for loop
So I did loop
for(var i = 0; i < arrNum.length; i++){
console.log("")
console.log("Loop number is " + i)
if(arrNum[i] === arrNum[i]{
break
sameIndex = going[i]
}
}
console.log(sameIndex)
It's not working.
One way would be to use Array#indexOf. It returns the first index of the given element in the array:
var arrNum = [4, 7, 5, 3, 4, 5, 6, 7, 8, 10];
var i;
var sameIndex = -1;
for (i = 0; i < arrNum.length; i++) {
if (arrNum.indexOf(arrNum[i]) !== i) {
console.log('This is the second occurrence of', arrNum[i]);
sameIndex = arrNum.indexOf(arrNum[i]);
break;
}
}
console.log('The indices are', sameIndex, 'and', i);
If you're looking to get the first duplicate, then use :
var arrNum = [4,7,5,3,4,5,6,7,8,10];
function firstDuplicate(array){
var history = [];
for(var element of array){
if(history.indexOf(element)<0)
//not in the history yet
history.push(element);
else
return element;
}
return null; //or any distinctive value
}
var fDup = firstDuplicate(arrNum);
You could take a hash table and display the value.
var array = [4, 7, 5, 3, 4, 5, 6, 7, 8, 10],
hash = Object.create(null),
i;
for (i = 0; i < array.length; i++) {
if (hash[array[i]]) {
console.log('first dupe: ' + array[i]);
break;
}
hash[array[i]] = true;
}
A working script:
var arrNum = [4,7,5,3,4,5,6,7,8,10];
var sameIndex = -1, going = new Array();
for(var j = 0; j < arrNum.length; j++) {
for(var i = 1; i < arrNum.length; i++){
console.log("Loop number is " + j + ", " + i)
if(arrNum[i] === arrNum[j]){
sameIndex = i;
break;
}
}
if(sameIndex > 0) {
console.log(j, sameIndex)
break;
}
}
var arrNum = [4,7,5,3,4,5,6,7,8,10];
for(var i = 0; i < arrNum.length; i++){
for(var j = i+1; j < arrNum.length; j++) {
if(arrNum[i] === arrNum[j]) {
console.log('value: '+arrNum[i]+' index1: '+i+' index2: '+j);
}
}
}
Iterate over the original array and if the value is not in a comparison array - push it into a common numbers array. The first item in that common numbers array is the target.
var origArray = [4,7,5,3,4,5,6,7,8,10];
var newArray = [];
var commonNums = [];
origArray.forEach(function(item,i) {
newArray.indexOf(item) == -1
? newArray.push(item)
: commonNums.push({item: item, index:i});
})
if(commonNums.length > 0) {
var firstCommonNum = commonNums[0].item;
var firstCommonNumIndex = commonNums[0].index;
console.log("common number " + firstCommonNum);
console.log("Loop number is " + firstCommonNumIndex);
}

Javascript sum of arrays and average

I have an issue with getting the sum of two arrays and combining their averages while rounding off.
I don't want to hardcode but rather pass two random arrays. so here is the code but it keeps returning NaN
function sumAverage(arr) {
var result = 0;
// Your code here
// set an array
arr = [];
a = [];
b = [];
arr[0] = a;
arr[1] = b;
var sum = 0;
// compute sum of elements in the array
for (var j = 0; j < a.length; j++) {
sum += a[j];
}
// get the average of elements in the array
var total = 0;
total += sum / a.length;
var add = 0;
for (var i = 0; i < b.length; i++)
add += b[i];
var math = 0;
math += add / b.length;
result += math + total;
Math.round(result);
return result;
}
console.log(sumAverage([
[2, 3, 4, 5],
[6, 7, 8, 9]
]));
If you wanted to do it a bit more functionally, you could do something like this:
function sumAverage(arrays) {
const average = arrays.reduce((acc, arr) => {
const total = arr.reduce((total, num) => total += num, 0);
return acc += total / arr.length;
}, 0);
return Math.round(average);
}
console.log('sum average:', sumAverage([[1,2,3], [4,5,6]]));
Just try this method..this kind of issues sometimes occured for me.
For example
var total = 0;
total = total + sum / a.length;
And every concat use this method..
Because you are assigning the value [] with the same name as the argument? This works, see jFiddle
function sumAverage(arr) {
var result = 0;
//arr = [];
//a = [];
//b = [];
a = arr[0];
b = arr[1];
var sum = 0;
// compute sum of elements in the array
for(var j = 0; j < a.length; j++ ){
sum += a[j] ;
}
// get the average of elements in the array
var total = 0;
total += sum / a.length;
var add = 0;
for(var i = 0; i < b.length; i++)
add += b[i];
var math = 0;
math += add / b.length;
result += math + total;
Math.round(result);
return result;
}
document.write(sumAverage([[2,3,4,5], [6,7,8,9]]));
As said in comments, you reset your arguments...
Use the variable "arguments" for dynamic function parameters.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
I suggest to use two nested loops, one for the outer array and one for the inner arrays. Then sum values, calculate the average and add averages.
function sumAverage(array) {
var result = 0,
sum,
i, j;
for (i = 0; i < array.length; i++) {
sum = 0;
for (j = 0; j < array[i].length; j++) {
sum += array[i][j];
}
result += Math.round(sum / array[i].length);
}
return result;
}
console.log(sumAverage([[2, 3, 4, 5], [6, 7, 8, 9]])); // 12
The problem is that you are emptying arr by saying arr = [].
Later, you are iterating over a which is empty too.
Again when you say total += sum / a.length;, sum is 0 and a.length is 0 so 0/0 becomes NaN. Similarly for math. Adding Nan to NaN is again NaN and that's what you get.
Solution is to not empty passed arr and modify your code like below:
function sumAverage(arr) {
var result = 0;
// Your code here
// set an array
//arr = [];
//a = [];
//b = [];
a = arr[0];
b = arr[1];
var sum = 0;
// compute sum of elements in the array
for (var j = 0; j < a.length; j++) {
sum += a[j];
}
// get the average of elements in the array
var total = 0;
total = sum / a.length;
var add = 0;
for (var i = 0; i < b.length; i++)
add += b[i];
var math = 0;
math = add / b.length;
result = math + total;
result = Math.round(result);
return result;
}
console.log(sumAverage([
[2, 3, 4, 5],
[6, 7, 8, 9]
]));
Basically I see a mistake here:
arr[0] = a; arr[1] = b;
That should be
a= arr[0]; b= arr[1];
and then remove:
arr = [];
I suggest you write your function like this:
function sum(arr) {
var arr1 = arr[0]
var sum1 = 0;
arr1.map(function(e){sum1+=e});
var arr2 = arr[1]
var sum2 = 0;
arr2.map(function(e){sum2+=e});
return Math.round(sum1/arr1.length + sum2/arr2.length);
}

Categories