What is the best possible way to reduce an array of ranges in javascript.
For example I have
1-3,4-5,10-12,2-4
the result I need for this is
1-5, 10-12
What is the best way to tackle this problem ?
I would first create another array with no duplicates, storing the numbers that are covered by the ranges:
1-3 covers 1, 2, 3 --> [1, 2, 3]
4-5 covers 4, 5 --> [1, 2, 3, 4, 5]
10-12 covers 10, 11, 12 --> [1, 2, 3, 4, 5, 10, 11, 12]
2-4 covers 2, 3, 4 --> [1, 2, 3, 4, 5, 10, 11, 12]
Then, sort the array:
[1, 2, 3, 4, 5, 10, 11, 12] // nothing changed in this example
Finally, rebuild the ranges, depending on the consecutive values:
1-5
10-12
1) parse the input to build a structure like this:
var rlist = [
{min: 1, max: 3},
{min: 4, max: 5},
{min: 10, max: 12}
{min: 2, max: 4}
];
2) marge each interval of that list into a new list:
var olist = [], i, j, r, p, s;
for (i = 0; i < rlist.length; ++i) {
r = rlist[i];
for (j = 0; j < olist.length; ) {
p = olist[j];
if (r.max+1 < p.min) {
// insert here
break;
} else if (p.max+1 >= r.min) {
// intersection
olist.splice(j, 1);
r.min = p.min;
r.max = Math.max(r.max, p.max);
} else {
++j;
}
}
olist.splice(j, 0, r);
}
3) Convert result into a string
s = "";
for (j = 0; j < olist.length; ++j) {
if (j > 0) {
s += ",";
}
s += olist[j].min + "-" + olist[j].max;
}
Fiddle
Related
const diagonalSum = function (arr) {
var length=arr.length -1;
var sum=0;
for(let i=0;i<arr.length;i++){//1<3
sum+= arr[i][i]+arr[i][length-i]//[1][0]+
}
return sum;
};
tried this , but 2nd and 3rd test cases are not getting passed. Any other logic?
const diagonalSum = function (arr) {
var length=arr.length -1;
var sum=0;
for(let i=0;i<arr.length;i++){//1<3
sum+= arr[i][i]+arr[i][length-i]//[1][0]+
}
return sum;
};
searching any other logic
This will work for you.
// An efficient Javascript program to find
// sum of diagonals
function printDiagonalSums(mat,n)
{
let principal = 0, secondary = 0;
for (let i = 0; i < n; i++) {
principal += mat[i][i];
}
document.write("Principal Diagonal:"
+ principal+"<br>");
}
// Driver code
let a = [[ 1, 2, 3, 4, 5],
[5, 6, 7, 8, 5 ],
[ 1, 2, 3, 4, 5 ],
[ 5, 6, 7, 8, 5],
[ 5, 6, 7, 8, 5]];
printDiagonalSums(a, 5);
var valid1=[4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
function validateCred(array) {
let doubleArray =0
for(i=array.length-2; i >= 0; i-=2) {
doubleArray= array[i]*2
}
console.log(doubleArray);
}
validateCred(valid1) //prints 8 I want it to print entire loop
Im trying to code luhn Algorithm and this is the first step of doubling every second number from the back, i want my result to equal doubleArray however when i try print it only 8 prints
you have only 8 prints because you have step i-2. Also, see comments in code about reversing an array
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
function validateCred(array) {
let doubleArray = [];
// we should move through all iterations that is why step i-=1
for(let i = array.length-1; i >= 0; i -= 1) {
// moving from the end of the array we will get reversed copy if using method push()
// that is why changed to unshift()
doubleArray.unshift((array.length - 1 - i) % 2 == 0 ? array[i] * 2 : array[i]);
// array.length - 1 - i - using because we need to move from right in case length not odd
}
console.log(doubleArray);
}
// ES6+ syntax version version
function esValidateCred1(array) {
const doubleArray = array.reverse().map((i, ind) => ind % 2 === 0 ? i*2 : i).reverse();
console.log(doubleArray);;
}
validateCred(valid1);
esValidateCred1(valid1);
You can refer the code below to get the desired output i.e. the an array with doubled value starting from back.
var valid1=[4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
function validateCred(array) {
let doubleArray = [];
for(i=array.length-2; i >= 0; i-=2) {
doubleArray.push(array[i] * 2)
}
return(doubleArray);
}
console.log(validateCred(valid1))
the easiest way is to use .map() method for array
var valid1=[4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
function validateCred(array) {
return array.map(item => item*2);
}
console.log( validateCred(valid1) ) //prints array doubled elements
I'm trying to compare two arrays at the same time and log the only the even values. This is the code I came up with, which does log correctly, but I'm certain this is not the correct way. How can I improve this code?
"Take arr1 and arr2 and log only the even ones"
const arr1 = [5,8,2,1,5,7,3,4,5,8,1,2,4,8,3,1,4,5];
const arr2 = [15,26,74,12,3,6,9,1,2,5];
for (var i=0; i < arr1.length; i++) {
if ((arr1[i] % 2) === 0) {
console.log(arr1[i]);
}
}
for (var i=0; i < arr2.length; i++) {
if ((arr2[i] % 2) ===0) {
console.log (arr2[i]);
}
}
Concat your arrays and then run the code on the single array.
const arr1 = [5, 8, 2, 1, 5, 7, 3, 4, 5, 8, 1, 2, 4, 8, 3, 1, 4, 5];
const arr2 = [15, 26, 74, 12, 3, 6, 9, 1, 2, 5];
const mergedArray = arr1.concat(arr2);
for (var i = 0; i < mergedArray.length; i++) {
if ((mergedArray[i] % 2) === 0) {
console.log(mergedArray[i]);
}
}
You could also just traverse both arrays in one loop and check for even numbers in both if you can't add more space. It would be even more efficient to run two for loops, where the first goes from 0 to min(arr1.length, arr2.length) and the second goes from min(arr1.length, arr2.length) to max(arr2.length,arr1.length) (of course you'd have to check to see which is bigger in advanced). Also I believe you should go here for questions related to improving the efficiency of code that runs correctly.
const arr1 = [5, 8, 2, 1, 5, 7, 3, 4, 5, 8, 1, 2, 4, 8, 3, 1, 4, 5];
const arr2 = [15, 26, 74, 12, 3, 6, 9, 1, 2, 5];
const mx = Math.max(arr1.length, arr2.length);
for (var i = 0; i < mx; i++) {
if ( i < arr1.length && (arr1[i] % 2 === 0)) {
console.log(arr1[i]);
}
if ( i < arr2.length && (arr2[i] % 2 === 0)) {
console.log(arr2[i]);
}
}
I want a function that returns the sub array which takes a position & the no. of elements I want. I think there may be some algorithm to find the pivot point or something & from that I can get the sub array, but I totally forgot it.
Example: a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I want 6 elements
if position = 0, then I want [1, 2, 3, 4, 5, 6]
if position = 1, then [1, 2, 3, 4, 5, 6]
if position = 2, then [1, 2, 3, 4, 5, 6]
if position = 3, then [1, 2, 3, 4, 5, 6]
if position = 4, then [2, 3, 4, 5, 6, 7]
if position = 5, then [3, 4, 5, 6, 7, 8]
if position = 6, then [4, 5, 6, 7, 8, 9]
if position = 7, then [5, 6, 7, 8, 9, 10]
if position = 8, then [5, 6, 7, 8, 9, 10]
if position = 9, then [5, 6, 7, 8, 9, 10]
simply get the middle of N elements based on the position I pass.
I can write up my own loop which will contain multiple if-else conditions to get it done. But I feel there may be some easy way to do it.
I didnt include my incomplete code snippet because I strongly feel there must be some algorithm to do this.
What you want is : Array.prototype.slice(...)
It's neatly documented here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
var n = 6;
var start = Math.max(0, Math.min(Math.floor(position-n/2), a.length-n));
return a.slice(start, start+n);
Simple way:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
function getSubArray(idx, _length, _array) {
return _array.slice(idx, idx + _length);
}
var subArray = getSubArray(3, 6, a);
You could use an offset for the postion and get the the start value first for slicing.
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
n = 6,
i,
start;
for (i = 1; i < 12; i++) {
start = Math.max(Math.min(i - n / 2, a.length - n), 0);
console.log(i, ': ', a.slice(start, start + n).join());
}
Your only need is to check if you are not gonna check a pos that doesn't exist. Like :
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var n = 6; // Number of result you want
var x = 8; // Pos you want
// If you gonna exceed your length, we got only the n last element
if((x+(n/2)) > a.length) {
console.log(a.slice(a.length-n));
// Otherwise, if under 0, we got the n first
} else
if((x-(n/2)) < 0) { console.log(a.slice(0,n) );
// Default case
} else {
console.log(a.slice((x-(n/2)),(x+(n/2))));
}
This is not the smartest way, but he can give you some hint. I used the slice as other mentionned to avoid a lot of if, but you should do GENERIC test.
Something like this :
a = [1,2,3,4,5,6,7,8,9,10];
n = 6;
function split(position) {
var start = Math.min(Math.max(position - Math.floor(n/2), 0), a.length - n);
var stop = Math.min(start+n, a.length);
return a.slice(start, stop);
}
No need for the Math object at all. You may simply do as follows;
function getArr(a,n,d){
n = n - 4 < 0 ? 0
: a.length - d > n - 4 ? n - 3
: a.length - d;
return a.slice(n,n + d);
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
diff = 6;
for (var i = 0; i < 10; i ++) console.log(JSON.stringify(getArr(arr,i,diff)));
no need of if-else you can use arr[position] to arr[8]. have you got
function getArr(arr,position,requiredNumbers){
return arr.slice(position, position+requiredNumbers);
}
I'm trying to create a sum function. When I run it through two different arrays (with same values), it's giving me different results. I can't really tell where I did wrong. It seems when I'm generating the array using the 'range' function, it's looping twice.
var myArr = [];
var tempArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function range(start, end) {
for (i = start; i <= end; i++) {
myArr.push(start);
start = start + 1;
}
return myArr;
}
function sum(arr) {
var sumArr = 0;
for (i = 0; i < arr.length; i++) {
sumArr = sumArr + arr[i];
//console.log(sumArr);
}
return sumArr;
}
console.log(range(1, 10)); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(tempArr); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(sum(range(1, 10))); //110
console.log(sum(tempArr)); //55
Any help would be appreciated. Thanks!
The reason is that var myArr = []; was a global variable. So pushed elements in the first console attempt will be there until they are cleared. You can use local variable in the function instead.
var tempArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function range(start, end) {
var myArr = [];
for (i = start; i <= end; i++) {
myArr.push(start);
start = start + 1;
}
return myArr;
}
function sum(arr) {
var sumArr = 0;
for (i = 0; i < arr.length; i++) {
sumArr = sumArr + arr[i];
//console.log(sumArr);
}
return sumArr;
}
console.log(range(1, 10)); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(tempArr); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(sum(range(1, 10))); //55
console.log(sum(tempArr)); //55
Using lodash :
You can use ._sum function.
var tempArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sum = _.sum(tempArr)
Don't forget to add the library if you want to use it.
<script src="https://cdn.jsdelivr.net/lodash/4.5.1/lodash.min.js"></script>
Demo