I'm trying to replace every third element in an array, but my code doesn't work.
//Calling of the first array
//first array
var numbers = new Array();
var go = true;
while (go) {
var n = parseFloat(prompt("Number please", ""));
numbers.push(n);
go = confirm("One more number?");
}
document.write("<p>" + numbers.toString() + "</p>");
// Array to change elements
// second array
for (var i = 0; i < numbers.length; i++)
if (numbers[i] % 3 == 0) {
(numbers *= 2);
}
else {
(numbers *= 1);
}
document.write("<p>" + numbers.toString() + "</p>");
//document.write("<p>");
Change numbers[i] % 3 to just i % 3. You're currently testing if the number in the array is a multiple of three instead of if its position in the array is a multiple of 3.
You also need to change your statements like numbers *= 2. numbers is an array, so multiplying it doesn't work well. If you want to update the individual array entry that should be numbers[i] *= 2;
You have missed the index in (numbers[i] *= 2) and in (numbers[i] *= 1);
And to check the third element you need to check the index (i+1)%3 == 0 because your array starts from index 0;
There are 2 mistakes apparent in your code:
numbers[i] % 3 == 0: this implies execute if block for any number a multiple of 3, not at every number on 3rd index
Solution: (i + 1) % 3 == 0
numbers *= 2 : you are trying to multiply an array not array element. You will get NaN.
Solution : numbers[i] *= 2;
Here's however another way of doing it using map:
numbers = numbers.map(function (i, idx) {
return (idx + 1) % 3 == 0 ? 2*i : i
})
Here's a doc to map function:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map?v=example
You want to check for index, I suppose not number value.
in for loop instead of
number[i] % 3
use
i % 3
You were using numbers[i] i.e the actual number instead of the index. So replace if(number[i]%3==0) to if(i%3==0).
Secondly, you are updating the whole array instead of an element of array in the if else condition. So use numbers[i] *=2 instead of number *= 2.
Use the below code snippet to change the array:
for (var i = 1; i <= numbers.length; i++)
if (i % 3 == 0) {
numbers[i] *= 2;
}
else {
numbers[i] *= 1;
}
}
Your logic here is wrong. Instead of taking the modulus of the value you should take the modulus of the index. Instead if if (numbers[i] % 3 == 0) this what you should have done is if (i % 3 == 0). Hope this helps.
You could change the whole program a bit, without using another variable for go.
As in comments mentioned, you could iteratig with a step length of 3 and omit the check with the remainder operator %.
Aor an assignment to an element of an array, you need the reference to the array with the variable name and the index on the left hand side and an assignment operator and the expression for getting the wanted result.
numbers[i] *= 2;
var n,
i,
numbers = [];
do {
n = parseFloat(prompt("Number please"));
numbers.push(n);
} while (confirm("One more number?"))
console.log(numbers);
for (i = 0; i < numbers.length; i += 3) {
numbers[i] *= 2;
}
console.log(numbers);
You can use the mathematical Modulus operator. Every third mean % 3.
https://www.w3schools.com/js/js_arithmetic.asp
If you use it in a condition, your index % 3 will return 0 when true.
if (index % 3 == 0)
Related
Can someone explain to me why my fibonacciGenerator function doesn't work with this code? I understand why it works with the second code tho but I just don't get why the first one doesn't.
function fibonacciGenerator(n) {
if (n > 0) {
var fArray = [];
fArray.push(0);
if (n >= 2) {
fArray.push(1);
}
for (var i = 0; i < n; i++) {
fArray.push(fArray[i] + fArray[i + 1]);
}
console.log(fArray);
}
}
fibonacciGenerator(1);
fibonacciGenerator(2);
Second code working :
function fibonacciGenerator(n) {
if (n > 0) {
var fArray = [];
fArray.push(0);
if (n >= 2) {
fArray.push(1);
}
for (var i = 2; i < n; i++) {
fArray.push(fArray[i - 1] + fArray[i - 2]);
}
console.log(fArray);
}
}
fibonacciGenerator(1);
fibonacciGenerator(2);
The first code is printing 2 extra Fibonacci number this is because:
you are first pushing 0 and 1 into the array as:
var fArray = [];
fArray.push(0);
if (n >=2 ){
fArray.push(1);
}
and then you loop over again till n times. Because of this reason it prints two extra Fibonacci numbers.
the solution is to either loop over n-2 time or to use the second code.
var fArray = [];
fArray.push(0);
if (n >= 2) {
fArray.push(1);
}
The initial condition is to cover n=1: [0] and n=2: [0,1]
The 2nd code is working because the loop only starts when n is greater than i, so means it skips the loop with n < 2.
For your problem, you don't skip the loop when n < 2.
for (var i = 0; i < n; i++) {
fArray.push(fArray[i] + fArray[i + 1]);
}
You can imagine the result will be like below when n < 2 with your loop.
Note that the inital value is fArray = [0]
fArray.push(fArray[0] + fArray[1]); //fArray[1] is undefined because you only have 1 item in your array
In this case fArray[0] + fArray[1] ==> 0 + undefined = NaN
So that's why your logic does not work when n < 2
To correct it, you need to avoid the loop if n < 2
//if n=1 or n=2, it won't trigger the loop due to `i < n-2`
for (var i = 0; i < n-2; i++) {
fArray.push(fArray[i] + fArray[i + 1]);
}
The idea to have i start with 0 instead of 2, and to adjust the body of the loop accordingly, is fine, but there is one thing that the first version didn't adjust: the stop condition of the loop.
By setting i=0, the first version loops 2 times more than the second version. You should also alter the end condition in the same way: instead of i < n, it should have i < n - 2, so to ensure the number of iterations is the same as in the second version.
Not related to your question, but the console.log should better be placed outside of the function. The job of the function should be to return the array, not to print it. So also, when n > 0 is false, it should return an empty array.
function fibonacciGenerator(n) {
var fArray = [];
if (n > 0) {
fArray.push(0);
if (n >= 2) {
fArray.push(1);
}
for (var i = 0; i < n - 2; i++) {
fArray.push(fArray[i] + fArray[i + 1]);
}
}
return fArray;
}
console.log(fibonacciGenerator(1));
console.log(fibonacciGenerator(2));
First you have to identify the pattern.
Fibonacci series -> 0 1 1 2 3 5 8 13 21
Term -> 0 1 2 3 4 5 6 7 8
0th term =0, 1st term =1
From the second term,
2nd = 1st term + 0th term = 1+0 = 1
3rd = 2nd term + 1st term = 1+1 = 2
4th = 3rd term + 2nd term = 2+1 = 3
5th = 4th term + 3rd term = 3+2 = 5
nth = (n-1) + (n-2)
since the first 2 terms are fixed, you have to start for loop from i= 2.
Also, according to the above shown pattern, you have to use following code inside the for loop.
fArray.push(fArray[i - 1] + fArray[i-2]);
While I was solving a question saying "add odd numbers from 1 to 20", I coded this:
var i, sum=0;
for (i=2; i<=20; i*2){
sum=sum+i;
}
document.write(sum);
When I launched it through a browser, it did not work. However, when I fixed i*2 into i+=2, it worked.
What am I missing? Am I not able to use *(multiplier) in For Loops?
If you need to add odd numbers from 1 to 20, then you need i+=2 as the third parameter of the for and need to initialize the variable to 1 to get the correct result:
var sum = 0;
for (var i = 1; i <= 20; i += 2) {
sum += i;
}
When you have
i += 2
2 is added to i and the result is stored into i. When you tried
var i, sum=0;
for (i=2; i<=20; i*2){
sum=sum+i;
}
i*2 calculates the value which is twice as big as i, but it will not change the value of i, so this would "work" instead:
var i, sum=0;
for (i=2; i<=20; i*=2){
sum=sum+i;
}
where
i *= 2
not only calculates the value twice as big as i, but stores the result into i as well. However, even though this will run, the result will not be correct, since you are using the wrong formula.
Also, you can calculate the result without using a for:
1 + 2 + ... + n = n * (n + 1) / 2
Assuming that n is pair: and since we know that we are "missing" half the numbers and all the pair numbers are bigger exactly with 1 than the previous impair numbers, we can subtract half of the sequence
n * (n + 1) / 2 - n / 2 = (n * (n + 1) - n) / 2 = (n * (n + 1 - 1)) /
2 = n * n / 2
and now we have exactly the double value of what we need, so the final formula is:
sum = n * n / 4;
Let's make this a function
function getOddSumUpTo(limit) {
if (limit % 2) limit ++;
return limit * limit / 4;
}
and then:
var sum = getOddSumUpTo(20);
Note that we increment limit if it is odd.
The issue is that you're not updating the value of the i in the for loop.
I want add odd numbers from 1 to 20
Then you need to change the initial value of i to 1.
var i, sum = 0;
for (i = 1; i <= 20; i += 2){
sum += i;
}
document.write(sum);
Also, you can find the sum of odd numbers from 1 to 20 by using a formula.
n = 20;
console.log(n % 2 == 0 ? (n * n)/ 4 : ((n + 1) * (n + 1))/4);
You can you just have to do it simillary to what you've written about sum.
You used there i += 2 and not i + 2.
The same way just change i * 2 to i *= 2.
Here is an working example
var i, sum = 0;
for (i = 2; i <= 20; i *= 2) {
console.log(i);
sum += i;
}
document.write(sum);
But a couple of things here.
First of all you wrote
add odd numbers from 1 to 20
and in all your examples you use sum on even numbers.
Secondly, by multiplying you will not achieve your desired goal (as you can see in a snippet above in a console)
So to actually
add odd numbers from 1 to 20
you should do it like this:
var i, sum = 0;
for (i = 1; i <= 20; i += 2) {
console.log(i);
sum += i;
}
document.write(sum);
EDIT
If you want to add even numbers you still can't use multiplying.
Why? Simply because you said yourself that you want a sum of numbers.
So let's say that we start with 2.
If we multiply it by 2 it has the value 4 which is fine.
But now look what happens in the next iteration. Our variable i which has the value 4 is multiplied by 2 and now its new value is 8. So what about 6?
Next iteration multiply 8 by 2 and its new value is 16.
Do you see where this is going?
And when you use i += 2 instead of i *= 2?
So if we start with 2 and than we add 2 its new value is 4.
In next iteration we add 2 to 4 and we have 6.
And so on.
If you want to test it, here is an example with multiplying and adding.
Pay attention to console logs
var i;
console.log("Multiplying");
for (i = 2; i <= 20; i *= 2) {
console.log("i value is: " + i);
}
console.log("Adding");
for (i = 2; i <= 20; i += 2) {
console.log("i value is: " + i);
}
What you are looking is this :
let sum = 0;
for(var i = 2; i <= 20; i += 2){
sum += i;
}
document.write(sum)
Another take on this :
// set to n (what you want). Set to n + 1
var N = 21;
// The main driver code create an array from 0-(N-1) and removes all even nums
let a = Array.apply(null, {length: N}).map(Number.call, _ => +_).filter(_=>_%2)
// console.log the array
console.log(a)
You can use whatever expression in loop header, even this is a valid for loop statement for (;;) which simply runs forever (equivalent to while(true)).
Problem is that you are not updating the i counter in for (i=2; i<=20; i*2) so the i will stays the same throughout the execution of the loop.
If you change it to for (i=2; i<=20; i = i*2) or for (i=2; i<=20; i *=2) then it will work.
It is the same as if you did
let i = 1;
i * 2;
console.log(i);
i = i * 2;
console.log(i);
The first i * 2 doesn't update the i while the second one does.
You can also translate the for loop into while loop to see the error more clearly.
// wrong
let i = 1;
while(i <= 20) {
i * 2;
// do something
}
// right
let i = 1;
while(i <= 20) {
i = i * 2 // or i *= 2
// do something
}
Just a side note, if you wanted to perform sum on more types of sequences efficiently than you could use a generator based approach and write your sum function and describe each type of a sequence with a generator function.
function *generateOdd(start, end) {
for (let i = start; i <= end; i++) {
if (i % 2 === 1) { yield i; }
}
}
function *generateEven(start, end) {
for (let i = start; i <= end; i++) {
if (i % 2 === 0) { yield i; }
}
}
function sumNums(gen, start, end) {
const generator = gen(start, end);
let res = 0;
let item = generator.next();
while (!item.done) {
res += item.value;
item = generator.next();
}
return res;
}
console.log(sumNums(generateOdd, 0, 20));
console.log(sumNums(generateEven, 0, 20));
/* sum of the Odd number using loop */
function sumOfOddNumbers(n){
let sum= 0;
for(let i = 1; i <= n; i++) {
if(i % 2 !== 0){
sum = sum + i;
}
}
return sum;
}
// 567 = 1+3+5+7+9+11+13+15+17+19+21+23+25+27+29+31+33+35+37+39+41+43+45+47
let n = 47;
let sum = sumOfOddNumbers(47);
alert('sumOfOddNumbers(' + n + ') = ' + sum);
I have made array and all but i only need function that clears every second item from list and doing that job until there is only 1 item left for example i need something to do in array from 1-10 including 1 and 10 the result need to be 5?
Any sugestions it is similar like this but only need it for javascript not python
How to delete elements of a circular list until there is only one element left using python?
I am using this inside html body tag
var num = prompt("type num");
var array = [];
for (i = 1; i <= num; i++) {
array.push(i);
}
document.write(array + "<br>");
I tried this so far but this does not finish jobs great
while (i--) {
(i + 1) % 2 === 0 && array.splice(i, 1)
}
It does only first time deleting and leave array 1 3 5 7 9 i need it to be only 5 in this case because prompt is 10 in my case
The circular part makes it pretty tricky. Your loop condition should be on array length > 1, and within the loop you have to manually mess with the counter once it exceeds the length of the array - 2. If it's equal to arr.length, you want to skip the first element of the array the next time around, otherwise begin with the first element. Sorry I'm not explaining it better, here is the code.
var arr = [1,2,3,4,5,6,7,8,9,10];
var i = 1;
while (arr.length > 1) {
console.log("removing " + arr[i]);
arr.splice(i, 1);
var left = arr.length - i;
if (left == 0)
i = 1;
else if (left == 1)
i = 0;
else
i++;
}
console.log("result " + arr[0]);
Edit - This is almost exactly The Josephus Problem or see the episode from Numberphile on Youtube
There is a short recursive way to solve it. The parameter n is the largest number (similar to an array of n numbers from 1 to n), and k being the number of positions to skip at a time, (every other being 2).
var josephus = (n, k) => {
if (n == 1) return 1;
return (josephus(n - 1, k) + k-1) % n + 1;
};
console.log(josephus(10, 2));
while(array.length > 1) {
array = array.filter((_, index) => index % 2 === 0);
}
Basically, get rid of every second index as long as the length is greater than 1. The callback for filter allows value as the first parameter and index as the second, per MDN.
i'm doing some coding exercises and i'm not being able to solve this one.
Find the sum of all divisors of a given integer.
For n = 12, the input should be
sumOfDivisors(n) = 28.
example: 1 + 2 + 3 + 4 + 6 + 12 = 28.
Constraints:
1 ≤ n ≤ 15.
how can i solve this exercise? i'm not being able to.
function(n){
var arr = [],
finalSum;
if(n <= 1 || n => 16){
return false ;
}
for(var i = 0; i < n; i++){
var tmp= n/2;
arr.push(tmp)
// i need to keep on dividing n but i can't get the way of how to
}
return finalSum;
}
This is another way to do it:
var divisors = n=>[...Array(n+1).keys()].slice(1)
.reduce((s, a)=>s+(!(n % a) && a), 0);
console.log(divisors(12));
JSFiddle: https://jsfiddle.net/32n5jdnb/141/
Explaining:
n=> this is an arrow function, the equivalent to function(n) {. You don't need the () if there's only one parameter.
Array(n+1) creates an empty array of n+1 elements
.keys() gets the keys of the empty array (the indexes i.e. 0, 1, 2) so this is a way to create a numeric sequence
[...Array(n+1)].keys()] uses the spread (...) operator to transform the iterator in another array so creating an array with the numeric sequence
.slice(1) removes the first element thus creating a sequence starting with 1. Remember the n+1 ?
.reduce() is a method that iterates though each element and calculates a value in order to reduce the array to one value. It receives as parameter a callback function to calculate the value and the initial value of the calculation
(s, a)=> is the callback function for reduce. It's an arrow function equivalent to function(s, a) {
s+(!(n % a) && a) is the calculation of the value.
s+ s (for sum) or the last value calculated +
!(n % a) this returns true only for the elements that have a 0 as modular value.
(!(n % a) && a) is a js 'trick'. The case is that boolean expressions in javascript don't return true or false. They return a 'truthy' or 'falsy' value which is then converted to boolean. So the actual returned value is the right value for && (considering both have to be truthy) and the first thuthy value found for || (considering only one need to be truthy). So this basically means: if a is a modular value (i.e. != 0) return a to add to the sum, else return 0.
, 0 is the initial value for the reduce calculation.
Reduce documentation: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Edit
Answering to Tristan Forward:
var divisorsList = [];
var divisors = (n)=>[...Array(n+1).keys()].slice(1)
.reduce((s, a)=>{
var divisor = !(n % a) && a;
if (divisor) divisorsList.push(divisor);
return s+divisor;
}, 0);
console.log('Result:', divisors(12));
console.log('Divisors:', divisorsList);
You have to check if specified number is or not a divisor of given integer. You can use modulo % - if there's no rest, specified number is the divisor of the given integer - add it to the sum.
function sumDivisors(num){
var sum = 0;
for (var i = 1; i <= num; i++){
if (!(num % i)) {
sum += i;
}
}
console.log(sum);
}
sumDivisors(6);
sumDivisors(10);
Here is a solution with better algorithm performance (O(sqrt(largest prime factor of n)))
divisors = n => {
sum = 1
for (i = 2; n > 1; i++) {
i * i > n ? i = n : 0
b = 0
while (n % i < 1) {
c = sum * i
sum += c - b
b = c
n /= i
}
}
return sum
}
since n / i is also a devisor this can be done more efficiently.
function sumDivisors(num) {
let sum = 1;
for (let i = 2; i < num / i; i++) {
if (num % i === 0) {
sum += i + num / i;
}
}
const sqrt = Math.sqrt(num);
return num + (num % sqrt === 0 ? sum + sqrt : sum);
}
function countDivisors(n){
let counter = 1;
for(let i=1; i <= n/2; i++){
n % i === 0 ? counter++ : null;
}
return counter
}
in this case, we consider our counter as starting with 1 since by default all numbers are divisible by 1. Then we half the number since numbers that can be able to divide n are less or equal to half its value
I've been trying to write code that multiplies even indexed elements of an array by 2 and odd indexed elements by 3.
I have the following numbers stored in the variable number, which represents an array of numbers
numbers = [1,7,9,21,32,77];
Even Indexed Numbers - 1,9,32
Odd Indexed Numbers - 7, 21, 77
Please keep in mind that arrays are Zero Indexed, which means the numbering starts at 0. In which case, the 0-Indexed element is actually 1, and the 1-Indexed element is 7.
This is what I expected the output to be
[2,21,18,63,64,231]
Unfortunately, I got this output
[2,14,17,42,64,154]
Here is the code for my method
numbers = numbers.map(function(x) {
n = 0;
while (n < numbers.length) {
if (n % 2 == 0) {
return x * 2;
}
else {
return x * 3;
}
n++;
}});
return numbers;
Here I created a while loop, that executes code for every iteration of the variable n. For every value of the variable n, I'm checking if n is even, which is used by the code n % 2 == 0. While it's true that 0 % 2 == 0 it's not true that 1 % 2 == 0. I'm incrementing n at the end of the while loop, so I don't understand why I received the output I did.
Any help will be appreciated.
You created a global property called n, by doing
n = 0;
and then,
while (n < numbers.length) {
if (n % 2 == 0) {
return x * 2;
} else {
return x * 3;
}
}
n++; // Unreachable
you always return immediately. So the, n++ is never incremented. So, n remains 0 always and so all the elements are multiplied by 2 always.
The Array.prototype.map's callback function's, second parameter is the index itself. So, the correct way to use map is, like this
numbers.map(function(currentNumber, index) {
if (index % 2 === 0) {
return currentNumber * 2;
} else {
return currentNumber * 3;
}
});
The same can be written succinctly, with the ternary operator, like this
numbers.map(function(currentNumber, index) {
return currentNumber * (index % 2 === 0 ? 2 : 3);
});
To complement the other answer, the source of OP's confusion is on how "map" works. The map function is already called for each element - yet, OP attempted to use a while loop inside it, which is another way to iterate through each element. That is a double interaction, so, in essence, if OP's code worked, it would still be modifying each number n times! Usually, you just chose between a loop or map:
Using a loop:
var numbers = [1,7,9,21,32,77];
for (var i=0; i<numbers.length; ++i)
numbers[i] = i % 2 === 0 ? numbers[i] * 2 : numbers[i] * 3;
Using map:
var numbers = [1,7,9,21,32,77];
numbers.map(function(number, index){
return number * (index % 2 === 0 ? 2 : 3);
});
Or, very briefly:
[1,7,9,21,32,77].map(function(n,i){ return n * [2,3][i%2]; });
Basically you want to return a modified array that if the elements of the initial one is:
in even position, then multiply the element by 2.
in odd position, then multiply the element by 3.
You can use map with arrow functions and the conditional (ternary) operator to get this one-liner
console.log([1,7,9,21,32,77].map((num,ind) => num * (ind % 2 === 0 ? 2 : 3)));
This will output the desired
[2, 21, 18, 63, 64, 231]