Every n times, skip n items and increase n by 1 - javascript

This is probably an odd question since I have a solution (below), but was hoping someone could show me a more succinct or readable way to do this:
I created a loop that outputs the following array:
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91]
the gaps between numbers get progressively larger:
1-0 = 1
3-1 = 2
6-3 = 3
10-6 = 4
...
91-78 = 13
etc.
I did it by creating two variables, step keeps track of the gap size and count keeps track of the current 'position' in the gap. count counts down to zero, then increases step by one.
var output = [];
var step = 0;
var count = 0;
for (var i = 0; i < 100; i++) {
if (count == 0){
step += 1;
count = step;
output.push(i);
}
count -= 1;
}

You can try the following:
var output = [];
var total = 0;
for (var i=1; i < 100; i++) {
output.push(total);
total += i;
}
The gaps between numbers simply increase by one for each step, so a for loop should be able to track this change.

You should skip useless iterations. If you want a sequence of 100 numbers, use
var output = [];
var step = 0;
for (var i = 0; i < 100; i++) {
step += i;
output.push(step);
}
If you want the general term,
aₙ = ∑ⁿᵢ₌₀ i = n*(n+1)/2
So you can also do
var output = [];
for (var i = 0; i < 100; i++) {
output.push(i * (i+1) / 2);
}

You can save the total helper variable with this solution:
var output = [0]
for (var i = 1; i < 14; i++) {
output.push(output[i - 1] + i)
}
console.log(output) // [ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91 ]
This solution takes into account that the value to add the counter value to is already present at the last position in the array.
A recursive version is also possible:
output = (function f(x) {
return x.length == 14 ? x : f(x.concat([x[x.length - 1] + x.length]))
})([0])
console.log(output); // [ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91 ]
Here is no additional counter variable is needed. I use concat because it returns an array what I need for the recursive call, where push returns the new array length. The argument for concat is an array with one element with the new value to add.
Try online

Related

How can I return only the number of matching pair values in array?

Say I found a box of loose shoes (all the same kind) at a garage sale, and I've created an array with each individual shoe listed by shoe size.
I want to display the number of paired values of shoe sizes in the array. For example, I have this array:
[10,10,10,10,20,20,20,30,50]
I would like to display 3 because we have 3 pairs of numbers:
10,10
10,10
20,20
And 3 remaining values that don't have a matching pair-value (20,30,50).
How can I do this?
function pairNumber(arr) {
var sorted_arr = arr.sort();
var i;
var results = [];
for (i = 0; i < sorted_arr.length; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
return results.length;
}
console.log(pairNumber([10, 10, 10, 10, 20, 20, 20, 30, 50]))
Here is another approach using a Set:
function pairNumbers(arr) {
let count = 0;
const set = new Set();
for (let i = 0; i < arr.length; i++) {
if (set.delete(arr[i])) {
count++;
} else {
set.add(arr[i])
}
}
return count;
}
console.log(pairNumbers([10, 10, 10, 10, 20, 20, 20, 30, 50])) // 3
I'd reduce into an object, counting up the number of occurrences of each number. Then reduce again on the Object.values of the object to count up the number of pairs, adding Math.floor(count / 2) to the accumulator on each iteration:
function pairNumber(arr) {
const itemCounts = arr.reduce((a, item) => {
a[item] = (a[item] || 0) + 1;
return a;
}, {});
return Object.values(itemCounts)
.reduce((pairsSoFar, count) => pairsSoFar + Math.floor(count / 2), 0);
}
console.log(pairNumber([10, 10, 10, 10, 20, 20, 20, 30, 50]))
Probably better to avoid .sort if possible - that increases the computational complexity from O(n) (minimum) to O(n log n).
If I understood the question well then this can be simplified even further by relying on sort initially...
Increment i to the next position after finding the pair and let the for loop increment it once again.
function pairNumber(arr) {
const sorted_arr = [...arr].sort(); // disallowing array mutation
let cnt = 0;
for (let i = 0; i < sorted_arr.length; i++) {
if (sorted_arr[i + 1] === sorted_arr[i]) {
cnt++;
i = i + 1;
}
}
return cnt;
}
console.log(pairNumber([10, 10, 10, 10, 10, 20, 20, 20, 20, 30, 30, 50]))
// 5 --> 2 pairs of 10, 2 pairs of 20, 1 pair of 30
console.log(pairNumbers([10, 10, 10, 10, 20, 20, 20, 30, 50]))
// 3 --> 2 pairs of 10 one pair of 20
Many thanks to all guys that help me understand more how to solve this issue.
After studying the answers in the post I come up with my own solution.
Thanks to you I understand I should increment i at the end of if to prevent a repetitive comparison.
function pairNumbers(arr) {
const sorted_arr = arr.sort();
const results = [];
for (let i = 0; i < sorted_arr.length; i++) {
if (sorted_arr[i] == sorted_arr[i + 1]) {
results.push(sorted_arr[i]);
i = i + 1;
}
}
return results.length;
}
console.log(pairNumbers([10, 10, 10, 10, 20, 20, 20, 30, 50])) // 3

Simplify array from many values to fewer

I have an array with many numbers (165) and want to 'simplify' the array to fewer numbers (50). The reduced array should still be representative for the 165 original numbers.
For example:
If I had this array with 8 values [2, 4, 3, 8, 1, 4, 9, 3] and would ask to reduce it to 4 values, I want to receive this array [3, 5.5, 2.5, 6]
Currently I have a function that works when the reduced number and the original number can be divided (as with 8 and 4) but when I try using it with let's say 165 values that should be simplified to 50 values it returns me 54 values:
const array = [28, 71, 64, 116, 128, 8, 78, 172, 142, 96, 12 ... 165 values]
const valuesToSum = Math.floor(array.length / 50); // 50 is the wanted array length
for (let i = 0; i < array.length; i++) {
if (i % valuesToSum !== 0 || i === 0) {
sum += array[i];
} else {
returnArray.push(sum / valuesToSum);
sum = 0;
}
}
return returnArray;
In the end this should be a JavaScript function but if someone could explain me this on a mathematical level it would help me a lot.
In order to get the exact number of groups you want, you can't round off the number of elements to group. For instance if you want to reduce from 165 to 50, some of the groups will have 3 elements, some will have 4.
To do this, use nested loops. The outer loop increments by the size of the group, while the inner loop increments by 1 within the group. The rounding happens when you convert this inner index to the array index.
const array = [28, 71, 64, 116, 128, 8, 78, 172, 142, 96, 12]
function reduceArray(array, newSize) {
const returnArray = [];
const valuesToSum = array.length / newSize;
for (let i = 0; i < array.length; i += valuesToSum) {
let sum = 0;
let j;
let start_i = Math.floor(i);
for (j = start_i; j < Math.min(start_i + valuesToSum, array.length); j++) {
sum += array[j];
}
returnArray.push(sum/(j - start_i));
}
return returnArray;
}
console.log(reduceArray(array, 4));
const bigArray = [];
for (let i = 0; i < 165; i++) {
bigArray.push(Math.floor(Math.random() * 200));
}
let result = reduceArray(bigArray, 50);
console.log(result.length);
console.log(result);

Javascript Array - showing the index of the lowest number

Complete JS newbie here!
I made an Array with a few numbers in it. I added a function that will show me the lowest number. My question can I show the index of the lowest number?(even If I would change the numbers)
Here is my code in case you need it:
function func()
{
var low= 0;
var numbersArr=[29, 26, 44, 80, 12, 15, 40];
for(var i = 0; i <= numbersArr.length;i++)
{
if(numbersArr[i]< numbersArr[i-1])
{
low = numbersArr[i];
}
}
console.log(low);
}
func();
You can also store value of i in one variable. See below code.
function func()
{
var numbersArr=[29, 26, 11, 44, 80, 12, 15, 40,10];
var low = numbersArr[0];
var indexOfLow;
for(var i = 0; i <= numbersArr.length;i++)
{
if(numbersArr[i]< low)
{
low = numbersArr[i];
indexOfLow = i;
}
}
console.log("Lowest number is : "+low);
console.log("Index of lowest number is : "+indexOfLow);
}
func();
My question can I show the index of the lowest number?
You can do
numbersArr.indexOf(low)
Edit
That said, your logic of finding the lowest number isn't correct as you are only comparing the consecutive values of the array, try the updated logic in demo below.
Demo
function func() {
var numbersArr = [29, 26, 11, 44, 80, 12, 15, 40];
var low = numbersArr[0];
for (var i = 1; i <= numbersArr.length; i++) {
if (numbersArr[i] < low ) {
low = numbersArr[i];
}
}
console.log(low);
console.log(numbersArr.indexOf(low));
}
func();
You function lack the problem of keeping the lowest value, because you compare only the actual element and the element before.
function getLowestValue(array) {
var low = 0,
i;
for (i = 0; i < array.length; i++) { // just loop i < array.length!
if (array[i] < array[i - 1]) {
// ^^^^^^^^^^^^ this is the problem, you need to check against low
low = array[i];
}
}
return low;
}
console.log(getLowestValue([29, 26, 11, 80, 12, 15, 40])); // 12 instead of 11
You could store the value of the lowest element and compare with this value.
function getLowestValue(array) {
var low = array[0], // take the first element at index 0
i;
for (i = 1; i < array.length; i++) { // start with index 1, because you need to
// check against the last known smallest value
if(array[i] < low) {
low = array[i];
}
}
return low;
}
console.log(getLowestValue([29, 26, 11, 80, 12, 15, 40])); // 11 the right value
For getting the lowest index, you could just store the index instead of th value and take it for comparison.
function getLowestIndex(array) {
var lowIndex = 0,
i;
for (i = 1; i < array.length; i++) {
if (array[i] < array[lowIndex]) {
lowIndex = i;
}
}
return lowIndex;
}
console.log(getLowestIndex([29, 26, 11, 80, 12, 15, 40])); // 2
No need to make a function to find minimum value. You can use simply Math.min.apply to find minimum value from array and then indexOf to find index of that value
var numbersArr = [29, 26, 44, 80, 12, 15, 40];
var minValue = Math.min.apply(null, numbersArr);
console.log("Minimum Value:"+ minValue, "Index is:" + numbersArr.indexOf(minValue));
Solution:You will declair a variable which will hold the index of low number and assign it in the if statement as shown below:
if(numbersArr[i]< numbersArr[i-1])
{
low = numbersArr[i];
IndexLow=i;
}
I found a super easy way to do that, in your way. Just little change in your code. Please take a look.
function func()
{
var numbersArr=[29, 31, 26, 44, 80, 123, 151, 40,15];
var low= numbersArr[0];
var index = 0;
for(var i = 1; i < numbersArr.length;i++)
{
if(low >= numbersArr[i])
{
low = numbersArr[i];
index = i;
}
}
console.log(index);
console.log(low);
}
func();
Hope you found your problem. Happy coding :)

How to find first element that's less than the x in an array in Javascript?

I have this question in which I wanted to loop through an array starting from large number to smaller number and compare the number in the array against the x provided.
My code was supposed to be like this:
function convertToRoman(num) {
var decimalNum = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
while (num > 0){ // to prevent the number from reaching zero
for (var k = 0; k < decimalNum.length; k++) { //to loop through the array
if(num > decimalNum[k]) {return k}; //this is the part in which I wanted to return the element that is next in the array that is less than the num
}
}
}
convertToRoman(36);
For example, if the num = 36, then the next number in the array that is less than 36 would be 10. So I wanted to return 10. How do I do that?
I tried to find solutions online but the only solutions I found was for Java or C++ which is completely different from JavaScript, correct? And I don't think that binary search should be used as well...
Return the value not the index you are on:
function convertToRoman(pNumber) {
var array = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
for (var i = 0; i < array.length; i++) {
if (pNumber > array[i]) {//if the current item is smaller than the parameter
return array[i]; //return the value at the index you are on
};
}
}
console.log(convertToRoman(36));//returns 10
When you get to a item that is smaller, then return that item
for that you should get the value not index
function convertToRoman(num) {
var decimalNum = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
// while (num > 0) { // to prevent the number from reaching zero
for (var k = 0; k < decimalNum.length; k++) { //to loop through the array
if (num > decimalNum[k]) {
return decimalNum[k]
}; //this is the part in which I wanted to return the element that is next in the array that is less than the num
}
// }
}
console.log(convertToRoman(36));
Here's a solution that will work in IE and regardless of how the values in the array are sorted
var lesser = decimalNum.filter(function(dec) {
return dec < num;
});
var result = Math.max.apply(null, lesser);
If you know that the decimalNum array is alwys sorted the way it is in your code, you can simply replace the Math.max part with lesser[0]

Adding an element to an array from inside a for loop

in the for loop below I have arr[i] = x * i; I am basically trying to get multiples of numbers. the results of the code I have now is [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] I do not want the first element of the array to be 0 ..
var n = 10;
var arr = [];
var x = 2;
for(var i = 0; i < n; i++ ){
//arr[0] = x;
arr[i] = x * i;
// arr.push(x += x)
}
console.log(arr)
i want to be able to do arr[0] and see x. In this case that would be 2 (the number for the multiples..I don't know math words) [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
I know that the problem is that 2 * 0 is equal to 0 so arr[0] = 0. what is the best way to make it so that the first element will be the second loop. I was thinking about making an if statement. or using an array method that slices of the beginning of the array. I hope there is an easier way like changing the for loop.
There are two simple ways to fix this
Change the loop starting value
var arr = [],
x = 2,
n = 10;
for (var i = 1; i <= n; i++) { // Start with `1`
arr.push(x * i);
}
Or, multiply with the next value of i,
var arr = [],
x = 2,
n = 10;
for (var i = 0; i < n; i++) {
arr.push(x * (i + 1)); // Multiply with i + 1
}
If you still want to solve it with array index assignment, then just remove the first element, with Array.prototype.slice after creating the entire array, like this
var n = 10,
arr = [],
x = 2;
for (var i = 0; i <= n; i++) { // Note the limits, 0 to <= n
arr[i] = x * i;
}
console.log(arr);
// [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ]
arr = arr.slice(1);
console.log(arr);
// [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ]

Categories

Resources