Related
My code only prints the largest one, but I need to have the 4 largest numbers displayed and to be summed up.
let sizes = [3, 6, 2, 56, 32, 5, 89, 32];
let largest = sizes[0];
for (let x = 0; x < sizes.length; x++) {
if (largest < sizes[x] ) {
largest = sizes[x];
}
}
console.log(largest);;
Please use this code.
let sizes = [3, 6, 2, 56, 32, 5, 89, 32];
sizes.sort(function(a, b) { return b - a });
console.log(sizes.slice(0, 4).join(' '));
console.log(sizes.slice(0, 4).reduce((total, num) => total + num));
One method you can use is to sort your elements first, and then simply print out the first 4 elements:
sizes(function(a, b) {
return a - b;
});
console.log(sizes[0])
console.log(sizes[1])
console.log(sizes[2])
console.log(sizes[3])
There are easy solutions (sorting the array O(n log(n))) and there are performant solutions (O(n)) like:
let sizes = [3, 6, 2, 56, 32, 5, 89, 32];
let largest = sizes.slice(0, 4).sort((lhs, rhs) => rhs - lhs);
for (let x = 4; x < sizes.length; x++) {
if (largest[3] < sizes[x]) {
largest[3] = sizes[x];
largest = largest.sort((lhs, rhs) => rhs - lhs);
}
}
console.log(largest);
you can do that...
const
sizes = [3, 6, 2, 56, 32, 5, 89, 32]
, sumLargest = sizes.reduce((lg,x)=>
{
if (lg.length < 4) lg.push(x)
else
{
let min = Math.min(...lg)
if (x>min) lg[lg.indexOf(min)] = x
}
return lg
},[]).reduce((a,b)=>a+b,0)
console.log('sumLargest = ', JSON.stringify(sumLargest ))
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));
Very new to coding so please bear with me. I am attempting to solve this Kata on Codewars: https://www.codewars.com/kata/snail/train/javascript
Basically given an array like
[
[1, 2, 3, 4],
[12,13,14,5],
[11,16,15,6],
[10,9, 8, 7]
];
It would return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].
A snail trail spiraling around the outside of the matrix and inwards.
I am just solving for the case where the matrix is n x n where n is > 1 and an even number for now.
I got it working by declaring outputarray outside the function but I want that array to be declared within the function, hence the inclusion of this line: var outputarray = outputarray || [];
Not sure where I am going wrong.
snail = function(array) {
if (array.length == 0) {
return outputarray
}
var n = array[0].length - 1;
var outputarray = outputarray || [];
for (var i = 0; i <= n; i++) {
outputarray.push(array[0].splice(0, 1));
}
for (var i = 1; i <= n; i++) {
outputarray.push(array[i].splice(n, 1));
}
for (var i = n - 1; i >= 0; i--) {
outputarray.push(array[n].splice(i, 1));
}
for (var i = n - 1; i > 0; i--) {
outputarray.push(array[i].splice(0, 1));
}
array.pop();
array.shift();
snail(array);
}
Here's a non-recursive approach that doesn't mutate the input array. It works by keeping track of the top-left coordinate x, y and the size n of the spiral.
snail = function(array) {
const { length } = array;
const result = [];
let x = 0;
let y = 0;
let n = length;
while (n > 0) {
// travel right from top-left of spiral
for (let i = x; i < x + n; ++i) result.push(array[y][i]);
// shrink spiral and move top of spiral down
n--; y++;
// travel down from top-right of spiral
for (let i = y; i < y + n; ++i) result.push(array[i][x + n]);
// travel left from bottom-right of spiral
for (let i = x + n - 1; i >= x; --i) result.push(array[y + n - 1][i]);
// shrink spiral
n--;
// travel up from bottom-left of spiral
for (let i = y + n - 1; i >= y; --i) result.push(array[i][x]);
// move left of spiral right
x++;
}
return result;
}
console.log(snail([[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]));
One option is to define another function inside snail, which calls itself recursively, while also defining the outputarray inside snail. That way, outputarray isn't exposed to the outer scope, but the recursive function can still see it.
Also note that splice returns an array, so right now, your outputarray gets composed of an array of arrays. Spread into push instead to fix it, so that the outputarray becomes an array of numbers:
const input = [
[1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7]
];
const snail = (array) => {
const outputarray = [];
const iter = () => {
if (array.length == 0) {
return
}
var n = array[0].length - 1;
for (var i = 0; i <= n; i++) {
outputarray.push(...array[0].splice(0, 1));
}
for (var i = 1; i <= n; i++) {
outputarray.push(...array[i].splice(n, 1));
}
for (var i = n - 1; i >= 0; i--) {
outputarray.push(...array[n].splice(i, 1));
}
for (var i = n - 1; i > 0; i--) {
outputarray.push(...array[i].splice(0, 1));
}
array.pop();
array.shift();
iter(array);
};
iter(array);
return outputarray;
}
console.log(snail(input));
You could take some borders for the left, right, upper and lower indices and loop until no more indices are available.
function snail(array) {
var upper = 0,
lower = array.length - 1,
left = 0,
right = array[0].length - 1,
i = upper,
j = left,
result = [];
while (true) {
if (upper++ > lower) break;
for (; j < right; j++) result.push(array[i][j]);
if (right-- < left) break;
for (; i < lower; i++) result.push(array[i][j]);
if (lower-- < upper) break;
for (; j > left; j--) result.push(array[i][j]);
if (left++ > right) break;
for (; i > upper; i--) result.push(array[i][j]);
}
result.push(array[i][j]);
return result;
}
console.log(...snail([[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]));
This may not be according to the rules (or spirit?) of the kata, however, you can just glue it all together and sort.
function snail(trail) {
const numeric = (a, b) => a - b
const gather = (items, item) => items.push(parseInt(item, 10)) && items
const inline = (route, points) => points.reduce(gather, route) && route
const order = paths => paths.reduce(inline, []).sort(numeric)
return order(trail)
}
const trail = [
[1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7]
]
console.log(JSON.stringify(snail(trail)))
Try this:
const input = [
[1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7]
];
function snail(array) {
var res = [];
if (!array.length) return res;
var next = array.shift();
if (next) res = res.concat(next);
for (var i = 0; i < array.length; i++) {
res.push(array[i].pop());
}
next = array.pop()
if (next) res = res.concat(next.reverse());
for (var i = array.length - 1; i >= 0; i--) {
res.push(array[i].shift());
}
return res.concat(snail(array));
}
console.log(snail(input));
Here's my two cents, using the customary recursion:
function f(A){
return A.length > 1 ? A.splice(0,1)[0].concat(
f(A[0].map((c, i) => A.map(r => r[i])).reverse())) : A[0]
}
var A = [[ 1, 2, 3, 4], [12,13,14, 5], [11,16,15, 6], [10, 9, 8, 7]]
console.log(JSON.stringify(f(A)))
I tried to write a function that would find in a multidimensional array (with values from 3 to 7) repeating values for at least 3 times next to each other (vertical and horizontal). And if it finds that, change it for a different value. Let's say 1.
I tried to do this by loops but it doesn't seem to be a good way to solve that or I messed it up. Because for some array it works, for some it does not.
Here's my code:
function searching(array) {
for (i = 0; i < array.length; i++) {
let horizontal = array[i][0];
let howMany = 1;
for (j = 1; j < array[i].length; j++) {
if (horizontal === array[i][j]) {
howMany += 1;
horizontal = array[i][j];
if (howMany >= 3) {
for (d = j; d > j - howMany; d--) {
array[i][d] = 0;
}
}
} else {
horizontal = array[i][j];
howMany = 1;
}
}
}
for (v = 0; v < array.length; v++) {
let vertical = array[0][v];
let howMany = 1;
for (x = 1; x < array.length; x++) {
if (vertical === array[x][v]) {
howMany++;
vertical = array[x][v];
if (howMany >= 3) {
for (d = x; d > x - howMany; d--) {
array[d][v] = 0;
}
}
} else {
vertical = array[x][v];
howMany = 1;
}
}
}
}
The idea is to for example give array:
let array = [
[3, 4, 5, 6, 7],
[3, 4, 5, 6, 7],
[3, 4, 5, 5, 5],
[3, 5, 6, 7, 4]
]
And the result should be:
let result = [
[1, 1, 1, 6, 7],
[1, 1, 1, 6, 7],
[1, 1, 1, 1, 1],
[1, 5, 6, 7, 4]
]
Thanks in advance for any ideas how to solve it :) Greetings!
The problems with your current code are
(1) You're only checking individual rows and columns, when you need to be checking them both (eg, with [[2, 2], [2, 5]], when at the starting position [0][0], you need to look at both [0][1] (and its neighbors, if matching) as well as [1][0] (and its neighbors, if matching).
(2) You're not actually checking for adjacency at the moment, you're just counting up the total number of matching elements in a particular row or column.
Iterate over all indicies of the array. If an index has already been checked, return early. Recursively search for neighbors to that index, and if at least 3 matching in total are found, set them all to 1. Put all matching neighbors in the checked set to avoid checking them again (even if there were less than 2 adjacent matches found total).
setAllAdjacentToOne([
[3, 4, 5, 6, 7],
[3, 4, 5, 6, 7],
[3, 4, 5, 5, 5],
[3, 5, 6, 7, 4]
]);
// all 9s stay, the rest get set to 1:
setAllAdjacentToOne([
[2, 2, 9, 7, 7],
[2, 9, 9, 9, 7],
[3, 4, 4, 5, 5],
[9, 4, 5, 5, 9]
]);
function setAllAdjacentToOne(input) {
const output = input.map(subarr => subarr.slice());
const checked = new Set();
const getKey = (x, y) => `${x}_${y}`;
const width = input[0].length;
const height = input.length;
const getAllAdjacent = (x, y, numToFind, matches = []) => {
if (x >= width || x < 0 || y >= height || y < 0) {
return matches;
}
const key = getKey(x, y);
if (!checked.has(key) && input[y][x] === numToFind) {
checked.add(key);
matches.push({ x, y });
getAllAdjacent(x + 1, y, numToFind, matches);
getAllAdjacent(x - 1, y, numToFind, matches);
getAllAdjacent(x, y + 1, numToFind, matches);
getAllAdjacent(x, y - 1, numToFind, matches);
}
return matches;
};
output.forEach((innerRowArr, y) => {
innerRowArr.forEach((num, x) => {
const allAdjacent = getAllAdjacent(x, y, num);
if (allAdjacent.length <= 2) {
return;
}
allAdjacent.forEach(({ x, y }) => {
output[y][x] = 1;
});
});
});
console.log(JSON.stringify(output));
}
I didn't understand the question at first...
So this is my code:
let array = [
[3, 4, 5, 6, 7],
[3, 4, 5, 6, 7],
[3, 4, 5, 5, 5],
[3, 5, 6, 7, 4]
];
function replace(arr, target = 1) {
let needToChange = []; // save the index to change
const numbers = [3, 4, 5, 6, 7];
const m = arr.length; // m rows
const n = arr[0].length; // n columns
let mi = 0;
let ni = 0;
// search in row
for (mi = 0; mi < m; mi++) {
for (let x = 0; x < numbers.length; x++) {
const num = numbers[x]; // number to search
let counter = 0; // counter for this number in row mi
let tempArr = [];
for (ni = 0; ni < n; ni++) {
const currentNum = arr[mi][ni];
if (currentNum === num) {
counter++;
tempArr.push([mi, ni]);
}
}
if (counter >= 3) {
needToChange = needToChange.concat(tempArr);
}
}
}
// search in column
for (ni = 0; ni < n; ni++) {
for (let x = 0; x < numbers.length; x++) {
const num = numbers[x]; // number to search
let counter = 0; // counter for this number in row mi
let tempArr = [];
for (mi = 0; mi < m; mi++) {
const currentNum = arr[mi][ni];
if (currentNum === num) {
counter++;
tempArr.push([mi, ni]);
}
}
if (counter >= 3) {
needToChange = needToChange.concat(tempArr);
}
}
}
// replace
needToChange.forEach(([i, j]) => {
array[i][j] = target;
});
}
replace(array);
array.forEach(row => {
console.log(row.join(', '));
})
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)));