I have this array [2, 1, 2, 1, 1, 1, 1, 1]
I want if the sum of the values exceed four, it's make a new array in array.
I want a result like that: [[2,1],[2,1,1],[1,1,1]]
You could use Array#reduce and use it for adding the values of the last inserted array and for the whole result array.
The main part of the algorithm is this line
!i || r[r.length - 1].reduce(add, 0) + a > 4 ?
r.push([a]) :
r[r.length - 1].push(a);
In it, a check takes place, if i is zero (at start) or if the sum of the last array of the result is in sum with the actual item greater than 4, then a new array with the actual value is added. If not, then the element is pushed to the last array.
var data = [2, 1, 2, 1, 1, 1, 1, 1],
add = function (a, b) { return a + b; },
result = data.reduce(function (r, a, i) {
!i || r[r.length - 1].reduce(add, 0) + a > 4 ? r.push([a]) : r[r.length - 1].push(a);
return r;
}, []);
console.log(result);
You can loop through the array and build a new one, if the sum exceed 4 push the previous array into the result like:
var myArr = [2, 1, 2, 1, 1, 1, 1, 1];
var newArr = [];
var newInner = [];
for (var i = 0; i < myArr.length; i++) {
if (summArr(newInner) + myArr[i] > 4) {
newArr.push(newInner);
newInner = [];
}
newInner.push(myArr[i]);
if (i==myArr.length-1) newArr.push(newInner);
}
function summArr(arr) {
return arr.reduce(add, 0);
function add(a, b) {
return a + b;
}
}
Demo: https://jsfiddle.net/q0ps7960/
for simple way...
var array1 = [2, 1, 2, 1, 1, 1, 1, 1];
var tmp=[];
var output=[];
var sum=0;
for(var i=0; i<array1.length; i++){
sum +=array1[i];
if(sum<=4){
tmp.push(array1[i]);
}else{
output.push(tmp);
sum =array1[i];
tmp=[array1[i]];
}
}
output.push(tmp);
console.log(output);
Related
I have a number array [2, 1, 3, 4, 5, 1] and want to remove the smallest number in the list. But somehow my IF statement gets skipped.
I checked and by itself "numbers[i + 1]" and "numbers[i]" do work, but "numbers[i + 1] < numbers[i]" doesn't...
function removeSmallest(numbers) {
var smallestNumberKEY = 0;
for (i = 0; i <= numbers.lenths; i++) {
if (numbers[i + 1] < numbers[i]) {
smallestNumberKEY = i + 1;
}
}
numbers.splice(smallestNumberKEY, 1);
return numbers;
}
document.write(removeSmallest([2, 1, 3, 4, 5, 1]));
You have a typo in your code, array doesn't have lenths property
function removeSmallest(numbers) {
var smallestNumberKEY = 0;
for (var i = 0; i < numbers.length - 1; i++) {
if (numbers[i + 1] < numbers[i]) {
smallestNumberKEY = i + 1;
numbers.splice(smallestNumberKEY, 1);
}
}
return numbers;
}
document.write(removeSmallest([2, 1, 3, 4, 5, 1]));
But your algorithm wont work for another array, e.g [5, 3, 1, 4, 1], it will remove a value 3 too.
You can find the min value with Math.min function and then filter an array
function removeSmallest(arr) {
var min = Math.min(...arr);
return arr.filter(e => e != min);
}
You can use Array#filter instead
function removeSmallest(arr) {
var min = Math.min.apply(null, arr);
return arr.filter((e) => {return e != min});
}
console.log(removeSmallest([2, 1, 3, 4, 5, 1]))
Short one liner. If the smallest value exist multiple times it will only remove ONE. This may or may not be what you want.
const result = [6,1,3,1].sort().filter((_,i) => i) // result = [1,3,6]
It works by sorting and then creating a new array from the items where indeces are truthy(anything but 0)
another solution with splice and indexOf:
array = [2, 1, 3, 4, 5, 1];
function replace(arr){
arr = arr.slice(); //copy the array
arr.splice( arr.indexOf(Math.min.apply(null, arr)),1)
return arr;
}
document.write( replace(array) ,'<br> original array : ', array)
edit : making a copy of the array will avoid the original array from being modified
"Short" solution using Array.forEach and Array.splice methods:
function removeSmallest(numbers) {
var min = Math.min.apply(null, numbers);
numbers.forEach((v, k, arr) => v !== min || arr.splice(k,1));
return numbers;
}
console.log(removeSmallest([2, 1, 3, 4, 5, 1])); // [2, 3, 4, 5]
This is a proposal with a single loop of Array#reduce and without Math.min.
The algorithm sets in the first loop min with the value of the element and returns an empty array, because the actual element is the smallest value and the result set should not contain the smallest value.
The next loop can have
a value smaller than min, then assign a to min and return a copy of the original array until the previous element, because a new minimum is found and all other previous elements are greater than the actual value and belongs to the result array.
a value greater then min, then the actual value is pushed to the result set.
a value equal to min, then the vaue is skipped.
'use strict';
var removeSmallest = function () {
var min;
return function (r, a, i, aa) {
if (!i || a < min) {
min = a;
return aa.slice(0, i);
}
if (a > min) {
r.push(a);
}
return r;
}
}();
document.write('<pre>' + JSON.stringify([2, 1, 3, 2, 4, 5, 1].reduce(removeSmallest, []), 0, 4) + '</pre>');
I like this oneliner: list.filter(function(n) { return n != Math.min.apply( Math, list ) })
check it out here: https://jsfiddle.net/rz2n4rsd/1/
function remove_smallest(list) {
return list.filter(function(n) { return n != Math.min.apply( Math, list ) })
}
var list = [2, 1, 0, 4, 5, 1]
console.log(list) // [2, 1, 0, 4, 5, 1]
list = remove_smallest(list)
console.log(list) // [2, 1, 4, 5, 1]
list = remove_smallest(list)
console.log(list) // [2, 4, 5]
I had to do this but I needed a solution that did not mutate the input array numbers and ran in O(n) time. If that's what you're looking for, try this one:
const removeSmallest = (numbers) => {
const minValIndex = numbers.reduce((finalIndex, currentVal, currentIndex, array) => {
return array[currentIndex] <= array[finalIndex] ? currentIndex : finalIndex
}, 0)
return numbers.slice(0, minValIndex).concat(numbers.slice(minValIndex + 1))
}
function sumOfPaiars(ints){
var array = [];
var min = Math.min(...ints)
console.log(min)
for(var i=0;i<ints.length;i++){
if(ints[i]>min){
array.push(ints[i])
}
}
return array
}
If you only wish to remove a single instance of the smallest value (which was my use-case, not clear from the op).
arr.sort().shift()
Here is a piece of code that is work properly but is not accepted from codewars:
let numbers = [5, 3, 2, 1, 4];
numbers.sort(function numbers(a, b) {
return a - b;
});
const firstElement = numbers.shift();
Given a non-empty array, if there is a place to split the array so that the sum of the numbers on one side is equal to the sum of the numbers on the other side return the length of the two arrays as an array but if there is no place to split the array, return -1
canBalance([1, 1, 1, 2, 1]) → [3,2]
canBalance([2, 1, 1, 2, 1]) → -1
canBalance([10, 10]) → [1,1]
function canBalance(array) {
//Type your solutions here
}
module.exports = canBalance;
Make two variables, and add and subtract each item in the array until they are equal.
function canBalance(array) {
let start = 0, end = array.reduce((a, c) => a + c, 0);
for (let i = 0; i < array.length; i++) {
start += array[i];
end -= array[i];
if (start == end) {
return [i + 1, array.length - (i + 1)];
}
}
return -1;
}
console.log(canBalance([1, 1, 1, 2, 1]));
console.log(canBalance([2, 1, 1, 2, 1]));
console.log(canBalance([10, 10]));
loop through the array from the first (index 0) to the one before the last (length -1) since you want to check only until the second last to compare against the last one.
you can use slice to get the array minus the one element being iterated each time and use a reducer to get the sum
const reducer = (a, c) => a+c;
function canBalance(array) {
var result = [];
var arr = [];
for(var i=0; i<array.length - 1; i++){
arr.push(array[i]);
var leftover = array.slice(i+1,array.length);
if(arr.reduce(reducer) === leftover.reduce(reducer)){
result.push(arr.length);
result.push(leftover.length);
}
}
return result.length > 0 ? result : -1;
}
I have a matrix :
matrix = [[0, 1, 1, 2],
[0, 5, 0, 0],
[2, 0, 3, 3]]
I need to calculate Sum of all array elements which are not under 0
So, in this example Sum should be = 9
I have this function:
function matrixElementsSum(matrix) {
// Write your code here
var Summa =0
for (i = 0; i<4; i++){
var sum =0;
// console.log(matrix[i].length); //4
for(j=0; j<matrix.length; j++){
console.log("Matrix JI "+ matrix[j][i])
sum = sum +matrix[j][i];
if (matrix[j][i-1]!=0){
console.log(matrix[j][i-1])
Summa =Summa+ sum;
}
}
console.log('-----------' +Summa)
console.log("Sum "+sum);
}
return Summa;
}
i think i need to change if (matrix[j-1][i]!=0) but it doesn't work
You can use reduce() and inside forEach() loop for this. If the current element in foreach loop is zero then you can store index of that element in one other object zero and you can use that object to check if there was zero with same index.
var matrix = [
[0, 1, 1, 2],
[0, 5, 0, 0],
[2, 0, 3, 3]
]
var zero = {}
var sum = matrix.reduce(function(r, e, i) {
e.forEach(function(n, j) {
if (n == 0) zero[j] = true;
if (!zero[j]) r += n;
})
return r;
}, 0)
console.log(sum)
You can sum 2 arrays and ignore numbers from the bottom array, which items from the same index on the top array are 0.
Now you can iterate the matrix from the end, and sum the resulting array.
const matrix = [[0, 1, 1, 2], [0, 5, 0, 0], [2, 0, 3, 3]];
const sumNotUnderZero = (bottom, top) =>
top.map((v, i) => v ? v + bottom[i] : v);
const result = matrix.reduceRight(sumNotUnderZero)
.reduce((s, n) => s + n);
console.log(result);
You could use Array#reduceRight for building another array with valued column sums and then use Array#reduce for a single number.
var matrix = [[0, 1, 1, 2], [0, 5, 0, 0], [2, 0, 3, 3]],
result = matrix.reduceRight(function (a, b) {
return b.map(function (c, i) {
return c && c + a[i];
});
}).reduce(function (a, b) {
return a + b;
});
console.log(result);
Should be able to simplify it and use this:
function matrixElementsSum(matrix) {
var Summa =0
for (i = 0; i < matrix.length; i++)
for(j = 0; j < matrix[i].length; j++)
if (matrix[i-1][j] != 0)
Summa = Summa + matrix[i][j];
return Summa;
}
You need to access first the array above your current one, hence the matrix[i-1] and then the same column, hence the [j] in (matrix[i-1])[j] ~ matrix[i-1][j]
I found this JavaScript algorithm excercise:
Question:
From a unsorted array of numbers 1 to 100 excluding one number, how will you find that number?
The solution the author gives is:
function missingNumber(arr) {
var n = arr.length + 1,
sum = 0,
expectedSum = n * (n + 1) / 2;
for (var i = 0, len = arr.length; i < len; i++) {
sum += arr[i];
}
return expectedSum - sum;
}
I wanted to try and make it so you can find multiple missing numbers.
My solution:
var someArr = [2, 5, 3, 1, 4, 7, 10, 15]
function findMissingNumbers(arr) {
var missingNumbersCount;
var missingNumbers = [];
arr.sort(function(a, b) {
return a - b;
})
for(var i = 0; i < arr.length; i++) {
if(arr[i+1] - arr[i] != 1 && arr[i+1] != undefined) {
missingNumbersCount = arr[i+1] - arr[i] - 1;
for(j = 1; j <= missingNumbersCount; j++) {
missingNumbers.push(arr[i] + j)
}
}
}
return missingNumbers
}
findMissingNumbers(someArr) // [6, 8, 9, 11, 12, 13, 14]
Is there a better way to do this? It has to be JavaScript, since that's what I'm practicing.
You could use a sparse array with 1-values at indexes that correspond to values in the input array. Then you could create yet another array with all numbers (with same length as the sparse array), and retain only those values that correspond to an index with a 1-value in the sparse array.
This will run in O(n) time:
function findMissingNumbers(arr) {
// Create sparse array with a 1 at each index equal to a value in the input.
var sparse = arr.reduce((sparse, i) => (sparse[i]=1,sparse), []);
// Create array 0..highest number, and retain only those values for which
// the sparse array has nothing at that index (and eliminate the 0 value).
return [...sparse.keys()].filter(i => i && !sparse[i]);
}
var someArr = [2, 5, 3, 1, 4, 7, 10, 15]
var result = findMissingNumbers(someArr);
console.log(result);
NB: this requires EcmaScript2015 support.
The simplest solution to this problem
miss = (arr) => {
let missArr=[];
let l = Math.max(...arr);
let startsWithZero = arr.indexOf(0) > -1 ? 0 : 1;
for(i = startsWithZero; i < l; i++) {
if(arr.indexOf(i) < 0) {
missArr.push(i);
}
}
return missArr;
}
miss([3,4,1,2,6,8,12]);
Something like this will do what you want.
var X = [2, 5, 3, 1, 4, 7, 10, 15]; // Array of numbers
var N = Array.from(Array(Math.max.apply(Math, X)).keys()); //Generate number array using the largest int from X
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;}); //Return the difference
};
console.log(N.diff(X));
Option 1:
1. create a binary array
2. iterate over input array and for each element mark binary array true.
3. iterate over binary array and find out numbers of false.
Time complexity = O(N)
Space complexity = N
Option 2:
Sort input array O(nLogn)
iterate over sorted array and identify missing number a[i+1]-a[i] > 0
O(n)
total time complexity = O(nlogn) + O(n)
I think the best way to do this without any iterations for a single missing number would be to just use the sum approach.
const arr=[1-100];
let total=n*(n+1)/2;
let totalarray=array.reduce((t,i)=>t+i);
console.log(total-totalarray);
You can try this:
let missingNum= (n) => {
return n
.sort((a, b) => a - b)
.reduce((r, v, i, a) =>
(l => r.concat(Array.from({ length: v - l - 1 }, _ => ++l)))(a[i - 1]),
[]
)
}
console.log(missingNum([1,2,3,4,10]));
Solution to find missing numbers from unsorted array or array containing duplicate values.
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
var array1 = [1, 3, 4, 7, 9];
var n = array1.length;
var totalElements = array1.max(); // Total count including missing numbers. Can use max
var d = new Uint8Array(totalElements)
for(let i=0; i<n; i++){
d[array1[i]-1] = 1;
}
var outputArray = [];
for(let i=0; i<totalElements; i++) {
if(d[i] == 0) {
outputArray.push(i+1)
}
}
console.log(outputArray.toString());
My solution uses the same logic as trincot's answer
The time complexity is O(n)
const check_miss = (n) => {
let temp = Array(Math.max(...n)).fill(0);
n.forEach((item) => (temp[item] = 1));
const missing_items = temp
.map((item, index) => (item === 0 ? index : -1))
.filter((item) => item !== -1);
console.log(missing_items);
};
n = [5, 4, 2, 1, 10, 20, 0];
check_miss(n);
If I have the following array:
[0, 1, 3, 0, 4, 2]
And I'd like to sort it ascending order, barring zeros which I need on the end:
[1, 2, 3, 4, 0, 0]
Bear in mind I don't have access to underscore or linq.js for this solution.
My current solution works, but feels quite heavy, long, and not very elegant. Here's my code:
function sortNumbers(numbers) {
var zeroNumbers = [];
var notZeroNumbers = [];
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] === 0) {
zeroNumbers.push(numbers[i]);
} else {
notZeroNumbers.push(numbers[i]);
}
}
var sortedNumbers = notZeroNumbers.sort(function (a, b) {
return parseFloat(a) - parseFloat(b);
});
for (var x = 0; x < zeroNumbers.length; x++) {
sortedNumbers.push(zeroNumbers[x]);
}
return sortedNumbers;
}
Can I improve on this solution?
This is not related to this question, but I was searching for "pure sort javascript" and this is the first answer.
Because sort mutates the original array, the best practice when sorting an array is to clone it first.
const sortedArray = [...array].sort(/* optional comparison function*/)
simply try
var output = [0, 1, 3, 0, 4, 2].sort(function(a, b) {
a = a || Number.MAX_SAFE_INTEGER; //if a == 0 then it will be a falsey value and a will be assigned Number.MAX_SAFE_INTEGER
b = b || Number.MAX_SAFE_INTEGER;
return a - b;
});
console.log(output)
var arr = [0, 1, 3, 0, 4, 2, 9, 8, 7, 0];
arr.sort(function (left, right) {
return left == right ? 0 : (left === 0 ? 1 : (left < right ? -1 : 1));
});
console.log(arr)
This will always put zeroes at the end regardless of the size of the number.
Another alternative solution using Array.sort, Array.splice and Array.push functions:
var arr = [0, 1, 3, 0, 4, 2];
arr.sort();
while(arr[0] === 0) { arr.splice(0,1); arr.push(0); }
console.log(arr); // [1, 2, 3, 4, 0, 0]
You can use sort for this, which takes a closure/callback.
var sortedArray = [0, 1, 3, 0, 4, 2].sort(function(currentValue, nextValue) {
if(currentValue === 0) {
return 1;
} else {
return currentValue - nextValue;
}
});