Matrix elements sum - javascript

I want to get the sum of the matrix elements, except for those over which the number 0, and get error:
Uncaught TypeError: Cannot set property '0' of undefined
function matrixElementsSum(matrix) {
let s = 0;
for (var i = 0; i < matrix.length; i++) {
for (var j = 0; j <= matrix.length; j++) {
if (matrix[i][j] == 0) {
matrix[i+1][j] = 0;
}
s += matrix[i][j]
}
}
return s
}
console.log(matrixElementsSum([[0, 1, 2, 0],
[0, 3, 2, 1],
[2, 0, 2, 3]]))

Your loop counter i should iterate over number of rows and j should iterate over number of columns. Also before setting matrix[i+i][j] to 0, you should also check if i+1 < matrix.length (number of rows)
function matrixElementsSum(matrix) {
let s = 0;
for (var i = 0; i < matrix.length; i++) {
for (var j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] == 0 && i+1 < matrix.length) {
matrix[i+1][j] = 0;
}
s += matrix[i][j]
}
}
return s
}

Here is my solution to this problem. Hope it would help someone.
function matrixElementsSum(matrix) {
let susp = [];
return matrix.reduce((t, arr, i)=>{
return arr.reduce((tt, val, ii)=>{
if (val === 0) susp.push(ii);
if (susp.includes(ii)) {
return tt;
} else {
return tt+val;
}
}, 0) + t;
}, 0);
}

Here is my solution with Python:
def solution(matrix):
row_len = len(matrix)
col_len = len(matrix[0])
sum = 0
for c_index in range(col_len):
for r_index in range(row_len):
if matrix[r_index][c_index] == 0:
break
else:
sum += matrix[r_index][c_index]
return sum

function solution(matrix) {
let sum= 0;
for (let i = 0; i < matrix[0].length; i++) {
for (let j = 0; j < matrix.length; j++) {
if (matrix[j][i] === 0) break;
sum+= matrix[j][i];
}
}
return sum;
}

function solution(matrix) {
for(var r=0,j=0;j<matrix[0].length;j++){
for(var i=0;i<matrix.length;i++){
if(matrix[i][j]===0) break
else r+=matrix[i][j]
}
}
return r
}
It took me some time to solve this exercise. I see it was not very complicated.

Related

Correct merge sort

So... If I input:
4 1 5 3
INSTEAD OF 1,3,4,5
I GET [ 4, 1, 5, 3 ]
Following is the code for merge sort but for the last comparison the program doesn't fetch updated (1,4) (3,5) value rather (4,1) (5,3) thus giving the wrong result.
var a = [4, 1, 5, 3];
q(a);
function q(a) {
var start = 0;
var n = a.length;
var length = parseInt(n / 2);
if (n < 2) {
return n;
}
var l = [], r = [];
for (i = 0; i < length; i++) {
l[i] = a[i]; //left array
}
for (i = 0, j = length; j < n; i++ , j++) {
r[i] = a[j]; //right array
}
q(l); //merge sort left array
q(r); //merge sort right array
comp(l, r);
}
function comp(l, r) {
var k = [], m = 0, i = 0, j = 0;
while (i < ((l.length)) && j < ((r.length))) {
if (l[i] < r[j]) {
k[m] = l[i];
i++;
m++
}
else {
k[m] = r[j];
j++;
m++
}
}
while (i != (l.length)) {
k[m] = l[i];
m++;
i++;
}
while (j != (r.length)) {
k[m] = r[j];
m++;
j++;
}
console.log(k); //for final output it is [ 4, 1, 5, 3 ] instead of [1,3,4,5]
}
You have a couple small problems. The main one is that you are returning the wrong thing from your edge condition:
if (n < 2) {
return n; // n is just a length; doesn't make sense to return it.
}
n is the length, you really want to return the small array here:
if (n < 2) {
return a; // return the array instead
}
Also, you need to pass the result of the recursive call to your comp function. Right now you're just returning the original lists with:
comp(l, r)
Something like this would work better:
let l_sort = q(l); //merge sort left array
let r_sort = q(r); //merge sort right array
return comp(l_sort, r_sort); // merge the arrays when recursion unwinds.
And you need to return things for recursion to work.
Put all together:
function q(a) {
var start = 0;
var n = a.length;
var length = parseInt(n / 2);
if (n < 2) {
return a;
}
var l = [],
r = [];
for (i = 0; i < length; i++) {
l[i] = a[i]; //left array
}
for (i = 0, j = length; j < n; i++, j++) {
r[i] = a[j]; //right array
}
let l_sort = q(l); //merge sort left array
let r_sort = q(r); //merge sort right array
return comp(l_sort, r_sort);
}
function comp(l, r) {
var k = [],
m = 0,
i = 0,
j = 0;
while (i < ((l.length)) && j < ((r.length))) {
if (l[i] < r[j]) {
k[m] = l[i];
i++;
m++
} else {
k[m] = r[j];
j++;
m++
}
}
while (i != (l.length)) {
k[m] = l[i];
m++;
i++;
}
while (j != (r.length)) {
k[m] = r[j];
m++;
j++;
}
return k
}
console.log(q([4, 1, 5, 3]).join(','));
console.log(q([5, 4, 3, 2, 1]).join(','));
console.log(q([2, 3]).join(','));
console.log(q([3, 2]).join(','));
console.log(q([1]).join(','));

Why does function reassign 2Darray argument as sideeffect from calling the latter

When I run the third line alone and log test2darr it returns a 2D array filled with 6's in a 3x3 matrix
But when I run the fourth line and log test2darr again, it returns:
[4, 5, 4]
​
[5, 6, 5]​
[4, 5, 4]
(as well as for secondtest)
Though it should return the same array of 6's for test2darr and on assign the 2d array to secondtest
const n = 3;
const filler = new Array(n * n);
const test2darr = fill2DarrFromArr(filler.fill(6));
const secondtest = pileReduce(test2darr);
Here is my code for fill2DarrFromArr and pileReduce:
function pileReduce(_cells) {
_cells = fillEmpty(_cells);
for (let j = 0; j < _cells.length; j++) { //The Algorithm itself is not important
for (let i = 0; i < _cells.length; i++) { // But there might be some assignment problem that I missed
if (_cells[j][i] >= 4) {
_cells[j][i] = _cells[j][i] - 4;
if (j !== _cells.length - 1) _cells[j + 1][i]++;
if (j !== 0) _cells[j - 1][i]++;
if (i !== _cells.length - 1) _cells[j][i + 1]++;
if (i !== 0) _cells[j][i - 1]++;
}
}
}
return _cells;
}
function fill2DarrFromArr(_arr) {
let sideLength = Math.sqrt(_arr.length);
let out = create2DArr(sideLength, sideLength);
for (let j = 0; j < sideLength; j++) {
for (let i = 0; i < sideLength; i++) {
out[j][i] = _arr[j * sideLength + i];
}
}
return out;
}
function create2DArr(_n, _m) {
let _arr = new Array(_n);
for (let j = 0; j < _m; j++) {
_arr[j] = new Array(_m);
}
return _arr;
}
function fillEmpty(_arr) {
for (let j = 0; j < _arr.length; j++) {
for (let i = 0; i < _arr.length; i++) {
if (!_arr[j][i]) _arr[j][i] = 0;
}
}
return _arr;
}
Passing an array into a function doesn't create a copy of that array. Your functions are modifying the contents of the passed arrays, therefore they have side effects.

Combine 10 cycles into one in Javascript

Here's my code with cycles and I want to make it shorter (in one cycle if possible).
function plan(piece) {
for (i = 0; i < 10; i++) {
piece.addStep('right');
}
for (i = 0; i < 9; i++) {
piece.addStep('down');
}
for (i = 0; i < 8; i++) {
piece.addStep('left');
}
for (i = 0; i < 7; i++) {
piece.addStep('up');
}
}
etc... to i < 1
I thought about it that case,
function plan(piece) {
for (i=10; i>1; i--){
piece.addStep('right');
piece.addStep('down');
piece.addStep('left');
piece.addStep('up');
}
but it's was wrong. Help pls!
here's look of task(maze)
You can add function for the repeating logic :
function addSteps(piece, n) {
while (n--) {
piece.addStep(piece);
}
}
addSteps('right', 10);
addSteps('down', 9);
addSteps('left', 8);
addSteps('up', 7);
Simply combine all of them by introducing some if Checks.
For Example :
function plan(piece) {
for (i = 0; i < 10; i++) {
piece.addStep('right');
if(i < 9)
piece.addStep('down');
if(i < 8)
piece.addStep('left');
if(i < 7)
piece.addStep('up');
}
}
One option is:
function plan(piece) {
['right', 'down', 'left', 'up'].forEach((dir, ind) => {
for (let i = 0; i < 10 - ind; i++) {
piece.addStep(dir);
}
});
}
Doubt it is efficient, but you can be Array fill, concat, and forEach
var steps = [].concat(Array(10).fill("right"), Array(9).fill("down"), Array(8).fill("left"), Array(7).fill("up"))
steps.forEach(dir => piece.addStep(dir));
You could take nested loops and increment the index for getting the right direction.
var sequence = ['right', 'down', 'left', 'up'],
i, j,
k = 0,
l = sequence.length;
for (i = 0; i < 10; i++) {
for (j = i; j < 10; j++) {
document.getElementById('out').innerHTML += sequence[k] + '\n';
// or piece.addStep(sequence[k]);
}
++k;
k %= l;
}
<pre id="out"></pre>

How many times needed to Sort a number in an Array Javascript

I want to count how many times needed for an array to be sorted
var array = [4,2,3,1]
var yourCounter = 0;
for (var i = 0; i < array.length; i++) {
for (var j = 1; j < array.length-j; j++)
if (array[j - 1] > array[j]) {
yourCounter++;
} }
it will return 4 , it should be 5
but if I input array [1,2,3] will correctly return 0 , and if I input array [3,2,1] it will correctly return 3
You could take the given code and swap the values while counting.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
// Swap adjacent elements if they are in decreasing order
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]);
}
}
}
var array = [4, 2, 3, 1],
counter = 0,
i, j, n = array.length;
for (i = 0; i < n; i++) {
for (j = 0; j < n - 1; j++) {
if (array[j] > array[j + 1]) {
[array[j + 1], array[j]] = [array[j], array[j + 1]];
++counter;
}
}
}
console.log(counter);
console.log(array);
I found the solution
var a = [4,2,3,1]
function sortArray(a){
let swapCount = 0;
let swapOccurred = true;
let index = 0;
while (swapOccurred == true && index < a.length){
swapOccurred == false;
if (a[index] > a[index+1]){
let holder = a[index]
a[index] = a[index+1];
a[index+1] = holder;
swapOccurred == true;
swapCount ++;
index = -1;
}
index ++
}
function countSwaps(a) {
let swapCount = 0;
[a, swapCount] = sortArray(a)
console.log(swapCount)
}
return [a, swapCount]
}

Solution fails to pass one test with large inputs?

function birthdayCakeCandles(n, ar) {
// Complete this function
ar.sort();
var biggestNo = ar[(ar.length - 1)];
var total = 0;
for (var i = 0; i < ar.length; i++) {
if (ar[i] === biggestNo)
total++;
}
return total;
}
Here's the problem - https://www.hackerrank.com/challenges/birthday-cake-candles/problem
There is no need to sort the array, you can do the problem in O(n) times
function birthdayCakeCandles(arr, n) {
var total = 0;
var len = arr.length;
for (var i = 0; i < len; i++) {
if (ar[i] === n)
total++;
}
return total;

Categories

Resources