Sum of numbers on the perimeter from Array - javascript

I need to sum the numbers on the perimeter of this 2D array
const arr = [[1,5,3,4],
[4,9,9,7],
[3,8,7,4]];
The answer is 79 but i dont know how to write function.

You could visit all values and chgeck if the indices are either zero or the length of actual array minus one.
const
array = [[3, 8, 9, 7, 6], [6, 3, 8, 9, 7], [7, 6, 3, 8, 9]],
perimeter = array.reduce((sum, row, i, a) =>
row.reduce((s, v, j, b) =>
s + (i === 0 || j === 0 || i + 1 === a.length || j + 1 === b.length
? v
: 0,
sum)
),
0
);
console.log(perimeter);

This function will return all the perimeter numbers in a matrix, then flat and sum each item.
const arr = [[3, 8, 9, 7, 6], [6, 3, 8, 9, 7], [7, 6, 3, 8, 9]];
var snail = function(arr) {
let output = [];
output.push(arr[0]);
output.push(arr[arr.length - 1]);
for(let item of arr){
if(item != arr[0] && item != arr[arr.length - 1]){
output.push(item[0]);
output.push(item[item.length - 1]);
}
}
return output
}
const perimeter = snail(arr).flat(1);
const sum = perimeter.reduce((a, b) => a + b);
console.log(sum);

arr.map(ar => ar.reduce((a,b) => a + b, 0)).reduce((a,b) => a + b, 0)

Related

Return the sum of all even integers in array squared (javascript)

As the title says, I am trying to take an array of numbers, and then return the sum of all the even numbers in the array squared.
I can get my function to return the sum of all the even numbers in a given array, but cannot get it to square the sum of the even numbers.
Here is what I have so far:
let numStr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const squareEvenNumbers = (numStr) => {
let sum = 0;
for (let i = 0; i < numStr.length; i++) {
if (numStr[i] % 2 === 0) {
sum = Math.pow(sum + numStr[i], 2);
}
}
return sum
}
console.log(squareEvenNumbers(numStr));
You need to raise only the current item in the array to the power of 2, not the whole sum:
let numStr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const squareEvenNumbers = (numStr) => {
let sum = 0;
for (let i = 0; i < numStr.length; i++) {
if (numStr[i] % 2 === 0) {
sum += Math.pow(numStr[i], 2);
}
}
return sum
}
console.log(squareEvenNumbers(numStr));
Or, more concisely:
let numStr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const squareEvenNumbers = arr => arr
.filter(num => num % 2 === 0)
.reduce((a, num) => a + num ** 2, 0);
console.log(squareEvenNumbers(numStr));
Or, to only iterate over the array once:
let numStr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const squareEvenNumbers = arr => arr
.reduce((a, num) => a + (num % 2 === 0 && num ** 2), 0);
console.log(squareEvenNumbers(numStr));

Get distinct duplicates from array

I have an array [1,1,1,1,2,3,4,5,5,6,7,8,8,8]
How can I get an array of the distinct duplicates [1,5,8] - each duplicate in the result only once, regardless of how many times it appears in the original array
my code:
var types = availControls.map(item => item.type);
var sorted_types = types.slice().sort();
availControlTypes = [];
for (var i = 0; i < sorted_types.length - 1, i++) {
if (sorted_types[i + 1] == sorted_types[i])
availControlTypes.push(sorted_types[i]);
}
This gets me the duplicates, but not unique.
This will do it
var input = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
let filterDuplicates = arr => [...new Set(arr.filter((item, index) => arr.indexOf(item) != index))]
console.log(filterDuplicates(input))
You need a for loop, with an object that will hold the number of times the number appeared in the array. When the count is already 1, we can add the item to the result. We should continue to increment the counter, so we won't add more than a single duplicate of the same number (although we can stop at 2).
function fn(arr) {
var counts = {};
var result = [];
var n;
for(var i = 0; i < arr.length; i++) {
n = arr[i]; // get the current number
if(counts[n] === 1) result.push(n); // if counts is exactly 1, we should add the number to results
counts[n] = (counts[n] || 0) +1; // increment the counter
}
return result;
}
var arr = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
var result = fn(arr);
console.log(result)
const dupes = arr =>
Array.from(
arr.reduce((acc, item) => {
acc.set(item, (acc.get(item) || 0) + 1);
return acc;
}, new Map())
)
.filter(x => x[1] > 1)
.map(x => x[0]);
const arr = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
console.log(dupes(arr));
// [ 1, 5, 8 ]
ES6 1 liner.
This is very similar to how we find unique values, except instead of filtering for 1st occurrences, we're filtering for 2nd occurrences.
let nthOccurrences = (a, n = 1) => a.filter((v, i) => a.filter((vv, ii) => vv === v && ii <= i).length === n);
let x = [1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8];
let uniques = nthOccurrences(x, 1);
let uniqueDuplicates = nthOccurrences(x, 2);
let uniqueTriplets = nthOccurrences(x, 3); // unique values with 3 or more occurrences
console.log(JSON.stringify(uniques));
console.log(JSON.stringify(uniqueDuplicates));
console.log(JSON.stringify(uniqueTriplets));

How to sort even numbers ascending and odd numbers descending in an array?

I don't know how to sort the odd numbers in descending order on the right of the even ones. I'm kinda stuck here, I know I am missing something.
My output is like this: [2, 4, 6, 8, 10, 1, 3, 5, 7, 9]
It should be like this: [2, 4, 6, 8, 10, 9, 7, 5, 3, 1]
var n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
n.sort(function(a, b) {
return a % 2 - b % 2 || b % 2 - a % 2;
});
console.log(n);
A trivial and very expensive solution would be to build two arrays, sort them then concatenate them, but you can combine both tests and sort in place like this:
arr.sort((a,b)=> (a%2-b%2) || (a%2 ? b-a : a-b))
As you can see, the pattern for hierarchical sort is just
arr.sort(compareA || compareB)
which you can generalize for more conditions.
let arr = Array.from({length:10}, (_,i)=>i+1)
arr.sort((a,b)=> (a%2-b%2) || (a%2 ? b-a : a-b))
console.log(arr)
You can filter the odds and evens and, sort them and finally concatenate both arrays.
let n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let odds = n.filter((a) => a % 2 !== 0).sort((a, b) => b - a);
let even = n.filter((a) => a % 2 === 0).sort((a, b) => a - b);
let sorted = even.concat(odds);
console.log(sorted);
.as-console-wrapper { min-height: 100%; }
You can use filter() to get different arrays of even and odd numbers and then sort them and join then using Spread Operator
var n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let odd = n.filter(x => x % 2).sort((a,b) => b-a);
let even = n.filter(x => !(x % 2) ).sort((a,b) => a-b);
let res = [...even,...odd]
console.log(res);
Did you try splitting the array into two arrays (one for even and one for odd) then sort each one as you like and join them back using the spread operator [...even, ...odd]
var n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var even = n.filter(a => a % 2 == 0).sort();
var odd = n.filter(a => a % 2 != 0).sort().reverse();
var numbers = [...even, ...odd];
You can separate two array and merge by spread operator.
let n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let odd = n.filter (v => v % 2);
odd.sort((a,b) => b-a);
//console.log(odd)
let even = n.filter (v => !(v % 2));
even.sort((a,b) => a-b);
//console.log(even);
console.log([...even,...odd]);
var n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
odd = n.filter (v => v % 2);
odd.sort((a,b) => b-a);
//console.log(odd)
even = n.filter (v => !(v % 2));
even.sort((a,b) => a-b);
//console.log(even);
console.log([...even,...odd]);

Given a multi-dimensional array, return an array containing the sum of the diagonals

Given a multi-dimensional array, return an array containing the sum of the diagonals.
For example:
input:
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
output:
[ 7, 12, 15, 8, 3 ]
function addDiagonals(matrix) {
let sum = 0;
let j = matrix[0].length - 1;
for (let i = 0; i < matrix.length; i++, j--) {
sum += matrix[i][j];
sum += matrix[i][i];
}
return sum;
}
console.log(addDiagonals([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]));
I am able to find the sum of the diagonals. But I need to know how to go about finding the sum of each diagonal.
But I need to complete this:
function diagonalSum(matrix) {
let sum = 0;
let res = [];
for (let i = 0; i < matrix.length; i++) {
let j = matrix.length - i - 1;
res[i] = matrix[i][j];
console.log(`i = ${i} and j = ${j};`)
}
return res;
}
console.log(diagonalSum([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]));
Create an initial array of numbers (for the diagonal sums) first, then use reduce to iterate, using the x index and y index together with the array length to figure out the proper diagonal index the current number should be added to:
const input = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
const { length } = input;
const initial = new Array(length * 2 - 1).fill(0);
const output = input.reduce((a, subArr, y) => {
subArr.forEach((item, x) => {
const diagIndex = x - y + length - 1;
a[diagIndex] += item;
});
return a;
}, initial);
console.log(output);
Another example with a 4x4 array:
const input = [
[1, 2, 3, 9],
[4, 5, 6, 9],
[7, 8, 9, 9],
[2, 2, 2, 2]
];
const { length } = input;
const initial = new Array(length * 2 - 1).fill(0);
const output = input.reduce((a, subArr, y) => {
subArr.forEach((item, x) => {
const diagIndex = x - y + length - 1;
a[diagIndex] += item;
});
return a;
}, initial);
console.log(output);
The derivation of
const diagIndex = x - y + length - 1;
is: as y (column index) increases, if x (row index) stays the same, diagIndex should decrease, as you're getting closer to the bottom left corner and index 0 of the output sum array. So, on the right hand side of const diagIndex =, y is negative. As x increases, if y stays the same, diagIndex should increase, since you're getting farther away from the bottom left corner, so x is positive on the right-hand side.
We now have
const diagIndex = x - y + num;
where num is something else
We also know that at x = 0 and y = <square length - 1> (bottom left corner), the diagonal index should be 0, so:
diagIndex = x - y + num;
0 = 0 - (length - 1) + num
length - 1 = num
Plug that in:
const diagIndex = x - y + num;
const diagIndex = x - y + (length - 1);
Let's assume, just for now, that your current input is:
const input = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
Now, imagine we are placed on the last array of that matrix (i.e the array with [7, 8, 9]) and while iterating through indexes [0..4] (yea, from 0 to 4) of this array we trace a diagonal from the bottom-rigth to the top-left. So, the first and the last diagonal will be defined by the next elements:
First Diagonal: input[2][0] -> input[1][-1] -> input[0][-2]
Last Diagonal: input[2][4] -> input[1][3] -> input[0][2]
Now, suppose we map the undefined values that results of accessing the not defined indexes of those arrays to the number 0. Then, the sequences obtained from this approach will be:
(Diagonal 1): 7 -> 0 -> 0 => Sum = 7
(Diagonal 2): 8 -> 4 -> 0 => Sum = 12
(Diagonal 3): 9 -> 5 -> 1 => Sum = 15
(Diagonal 4): 0 -> 6 -> 2 => Sum = 8
(Diagonal 5): 0 -> 0 -> 3 => Sum = 3
I hope you have understood to this point because the next logic takes this approach for get the sum of the diagonals.
const input1 = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
const input2 = [
[1, 2, 3, 9],
[4, 5, 6, 9],
[7, 8, 9, 9],
[2, 2, 2, 2]
];
const getDiagonalsSums = (matrix) =>
{
let len = matrix.length;
let dSums = new Array(len * 2 - 1).fill(0);
for (var i = 0; i < dSums.length; i++)
{
for (var j = len - 1; j >= 0; j--)
{
dSums[i] += (matrix[j][i + j - len + 1] || 0);
}
}
return dSums;
}
console.log(JSON.stringify(getDiagonalsSums(input1)));
console.log(JSON.stringify(getDiagonalsSums(input2)));

Codewars javascript task - help to understand

I am taking an excercise on codewars:
Given a list of integers and a single sum value, return the first two
values (parse from the left please) in order of appearance that add up
to form the sum.
Example:
sum_pairs([10, 5, 2, 3, 7, 5], 10)
# ^-----------^ 5 + 5 = 10, indices: 1, 5
# ^--^ 3 + 7 = 10, indices: 3, 4 *
# * entire pair is earlier, and therefore is the correct answer
== [3, 7]
What do you think entire pair is earlier means? IMO if the sum of it's indexes is smallest. Now based on this assumption I made my solution and one test fails:
var sum_pairs=function(ints, s){
let i = 0;
let pair = [0, 0];
let ind = [100, 100]
let found = false;
function loop(i) {
if (i > ints.length) return pair;
ints.slice(i).forEach((curr, idx) => {
ints.slice(i+1).some((num, i) => {
let sum = curr + num;
let prevIndicies = ind[0] + ind[1];
if(sum === s && prevIndicies > idx + i) {
ind = [idx, i];
pair = [curr, num];
found = true;
return true;
}
})
})
i += 1;
loop(i)
}
loop(0)
if (found) {
return pair
}
return undefined;
}
console.log(sum_pairs([1,4,8,7,3,15], 8))
Test returns error that [1, 7] is expected.
I'm pretty sure what it means is they want the second element to be as leftward in the list as possible. For example, for
l5= [10, 5, 2, 3, 7, 5];
when trying to find a sum of 10, the desired output is
[3, 7]
[10, 5, 2, 3, 7, 5];
^ ^
instead of
[5, 5]
[10, 5, 2, 3, 7, 5];
^ ^
because the last element in [3, 7], the 7, came before the second 5.
This code seems to pass all test cases - iterate in a triangular fashion, starting at indicies [0, 1], [0, 2], [1, 2], [0, 3], [1, 3], [2, 3], ...:
const sum_pairs = function(ints, s){
const { length } = ints;
for (let i = 1; i < length; i++) {
for (let j = 0; j < i; j++) {
if (ints[i] + ints[j] === s) return [ints[j], ints[i]];
}
}
}
const sum_pairs=function(ints, s){
const { length } = ints;
for (let i = 1; i < length; i++) {
for (let j = 0; j < i; j++) {
if (ints[i] + ints[j] === s) return [ints[j], ints[i]];
}
}
}
l1= [1, 4, 8, 7, 3, 15];
l2= [1, -2, 3, 0, -6, 1];
l3= [20, -13, 40];
l4= [1, 2, 3, 4, 1, 0];
l5= [10, 5, 2, 3, 7, 5];
l6= [4, -2, 3, 3, 4];
l7= [0, 2, 0];
l8= [5, 9, 13, -3];
console.log(sum_pairs(l1, 8))
console.log(sum_pairs(l2, -6))
console.log(sum_pairs(l3, -7))
console.log(sum_pairs(l4, 2))
console.log(sum_pairs(l5, 10))
console.log(sum_pairs(l6, 8))
console.log(sum_pairs(l7, 0))
console.log(sum_pairs(l8, 10))
It means that you go from left to right and take the first matching pair, and since 7 is the first element that creats a pair (going from the left) 3 and 7 is the first pair.
I would solve it a bit easier:
function sum_pairs(arr, target) {
let old = [];
let result = [];
arr.some((el) => {
let found = old.find((oldEl) => oldEl + el === target);
if (found) return result = [found, el];
old.push(el);
})
return result;
}
sum_pairs([10, 5, 2, 3, 7, 5], 10);
Edit: an explaination. I loop over all elements in the array searching for a match i all the elements I have passed. If I find a match I remember it and break out of the loop by returning a "truthy" value. (That is just how .some() works.) Finally if I have not found a match I add the element to my list of old elements and go on to the next.
function sum_pair(arr,sum){
let result = [];
arr.forEach((i, j)=>{
if(i+arr[j+1]===sum){
console.log(i,arr[j+1], i+arr[j+1])
}
})
}
sum_pair([0, 3, 7, 0, 5, 5],10)

Categories