If statement involving modulo behaving erratically [duplicate] - javascript

This question already has answers here:
Looping through array and removing items, without breaking for loop
(17 answers)
Closed 2 years ago.
I'm making a function to create a list of prime numbers from 0 to num. I start off with a list of integers from 2 to num, and iterate over each one that goes from 2 to i < num; if at any point item % i === 0, the item is removed from the list. This works fine:
function getPrimes(num) {
// get list of ints from 2 to num
let primes = [...Array(num + 1).keys()];
primes = primes.splice(2);
let lastNumber = primes[primes.length - 1];
// make iterable, run its loop
// for each number in primes
for (let number of primes) {
// use iterable to remove if not prime
for (let i = 2; i < num; i++) {
if (number % i === 0) {
primes.splice(primes.indexOf(number), 1);
}
}
}
// add back two
primes.unshift(2);
return primes;
But when I try and make the iterable for each number only to up to Math.floor(num / 2) for the sake of efficiency, it breaks the code somehow:
function getPrimes(num) {
// get list of ints from 2 to num
let primes = [...Array(num + 1).keys()];
primes = primes.splice(2);
let lastNumber = primes[primes.length - 1];
// make iterable, run its loop
// for each number in primes
for (let number of primes) {
// use iterable to remove if not prime
for (let i = 2; i < Math.floor(num / 2); i++) {
if (number % i === 0) {
primes.splice(primes.indexOf(number), 1);
}
}
}
// add back two
primes.unshift(2);
return primes;
When I tried it out, getPrimes(10) gives me [ 2, 3, 5 ]. So seven is missing from the list of prime numbers from 0 to 10. Why is that? I checked and 7 modulo 2, 3, and 4 returns 1, 1, and 3, respectively. So why is the code in the loop running that removes 7 from primes? It's the only place in the code where I put that I wanted to remove a number from the array.

The first issue is that you are looping while removing items, which causes some items to be skipped. Loop backwards instead, so that only items that have already been checked are shifted. Second, num / 2 should be changed to Math.sqrt(number), as that is the maximum factor that needs to be checked before we can be sure that a number is prime. With this method, there is no need to add 2 back to the array.
function getPrimes(num) {
// get list of ints from 2 to num
let primes = [...Array(num + 1).keys()];
primes = primes.splice(2);
let lastNumber = primes[primes.length - 1];
// make iterable, run its loop
// for each number in primes
for(let i = primes.length - 1; i >= 0; i--){
let number = primes[i];
// use iterable to remove if not prime
for (let j = 2; j * j <= number; j++) {
if (number % j === 0) {
primes.splice(i, 1);
break;
}
}
}
return primes;
}
console.log(...getPrimes(10));

Related

undefined elements inside an array which has randomized numbers inside it

so I created this script to generate an array of 5 random numbers where the numbers must be unique, but I get +2 undefined elements. There are 5 numbers which are unique but the length of the array isn't anymore 5
let arr = [];
while (arr.length <= 5) {
let x = Math.floor(Math.random() * 11);
if (arr.includes(x) === false) {
arr.push(x);
}
arr.length += 1;
}
console.log(arr);
Thanks in advance guys.
You should remove the arr.length += 1 line. The array length will be automatically incremented each time a new element is pushed, no need to modify it by yourself: this is a bad practice.
the length is not 5 because this loop runs 6 times, arr.length = 0,1,2,3,4,5. and you have a 3 undefined elements because of ( arr.length += 1; ) this skips step 1,3,5.
let arr = [];
while (arr.length<5){
let x = Math.floor(Math.random()*11);
if (arr.includes(x) === false){
arr.push(x);
}
}
console.log(arr);

creating a function that only returns odd numbers [duplicate]

This question already has answers here:
How do I extract even elements of an Array?
(8 answers)
How to do a script for odd and even numbers from 1 to 1000 in Javascript?
(8 answers)
Closed 2 years ago.
I've spent an embarrassing amount of time on this question only to realize my function is only right 50% of the time. So the goal here is to return only the odd numbers of all the numbers in between the two arguments. (for instance if the arguments are 1 and 5 i'd need to return 2 & 3) the function I wrote is completely dependent on the first argument. if it's even my function will return odds, but if the first number is odd it'll return evens. does anyone know how i can fix this?
function oddNumbers(l, r) {
const arr = [];
const theEvens = [];
for (let i= l; i<r; i++) {
arr.push(i)
}
console.log(arr)
for (let i= 0; i < arr.length; i+= 2 ) {
const evens = arr[0] + i;
theEvens.push(evens);
}
theEvens.forEach(item => arr.splice(arr.indexOf(item), 1));
console.log(arr)
}
oddNumbers(2, 20);
I modified the code a bit to return only odd numbers
We use the % operator that behaves like the remainder operator in math:
so when we say i % 2 if the number is even the result of the operation will be 0
but when the "i" is an odd number the result will be 1
so now we can filter the even from the odd numbers using this operation
function oddNumbers(l, r) {
const arr = [];
for (let i= l; i<r; i++) {
if(i % 2 !== 0) arr.push(i);
}
console.log(arr);
}
oddNumbers(2, 20);
You can loop from initial to end parameters and get odd numbers using modulo, try this:
let result = [];
let returnOdd = (n1, n2) => {
for(i = n1; i < n2; i++){
if(i % 2 != 0){
result.push(i)
}
}
return result;
}
console.log(returnOdd(2, 20));
You could use the filter method.
This method creates a new array based on the condition it has. In this case it will to go through all the numbers in the array, and check if the number is odd (though the remainder operator).
For example:
1 % 2 = 1 ( true, keep in the new array )
2 % 2 = 0 ( false ignore in the new array )
function OddNumbers(start, end) {
// Create an array from the given range
const nums = Array(end - start + 1).fill().map((_, idx) => start + idx);
// Use filter to return the odd numbers via the % operator
return nums.filter(num => num % 2);
}
console.log(OddNumbers(2,20))

Determining if an array is a factor chain

I would love to know why this code is failing some tests. It is intentionally not using any ES6 code.
Here is the prompt:
*A factor chain is an array where each previous element is a factor of the next consecutive element. The following is a factor chain:
[3, 6, 12, 36]
// 3 is a factor of 6
// 6 is a factor of 12
// 12 is a factor of 36
Create a function that determines whether or not an array is a factor chain.*
My code:
function factorChain(arr) {
var isChain = true;
for (var i = 0; i < arr.length; i++) {
if ((arr[i + 1] / arr[i]) !== Math.floor(arr[i + 1] / arr[i])) {
isChain = false;
}
}
return isChain;
}
You should loop up to arr.length - 1 as you are accessing the element at the current index and the one at the next index on each iteration. Using the remainder operator to check if a number is a factor of another can enhance code clarity. Furthermore, there is no need to assign the result to a variable; simply returning false the first time the condition does not match will exit the function.
function factorChain(arr) {
for (var i = 0; i < arr.length - 1; i++) {
if (arr[i+1] % arr[i] != 0) {
return false;
}
}
return true;
}

Sum of Array of Odd numbers - JS

Given the triangle of consecutive odd numbers:
1
3 5
7 9 11
13 15 17 19
21 23 25 27 29
// Calculate the row sums of this triangle from the row index (starting at index 1) e.g.:
rowSumOddNumbers(1); // 1
rowSumOddNumbers(2); // 3 + 5 = 8
I tried to solve this using for loops:
function rowSumOddNumbers(n){
let result = [];
// generate the arrays of odd numbers
for(let i = 0; i < 30; i++){
// generate sub arrays by using another for loop
// and only pushing if the length is equal to current j
let sub = [];
for(let j = 1; j <= n; j++){
// if length === j (from 1 - n) keep pushing
if(sub[j - 1].length <= j){
// and if i is odd
if(i % 2 !== 0){
// push the i to sub (per length)
sub.push(i);
}
}
}
// push everything to the main array
result.push(sub);
}
// return sum of n
return result[n + 1].reduce(function(total, item){
return total += item;
});
}
My code above is not working. Basically I was planning to 1st generate an array of odd numbers less than 30. Next I need to create a sub array base on the length of iteration (j) that would from 1 - n (passed). Then finally push it to the main array. And then use reduce to get the sum of all the values in that index + 1 (since the index starts at 1).
Any idea what am I missing and how to make this work?
Most code problems involve some analysis first in order to spot patterns which you can then convert into code. Looking at the triangle, you'll see the sum of each row follows a pattern:
1: 1 === 1 ^ 3
2: 3 + 5 = 8 === 2 ^ 3
3: 7 + 9 + 11 = 27 === 3 ^ 3
... etc
So from the analysis above you can see that your code could probably be simplified slightly - I won't post an answer, but think about using Math.pow.
No need for any loops.
function rowSumOddNumbers(n) {
// how many numbers are there in the rows above n?
// sum of arithmetic sequence...
let numbers_before_n_count = (n - 1) * n / 2;
let first_number_in_nth_row = numbers_before_n_count * 2 + 1;
let last_number_in_nth_row = first_number_in_nth_row + 2 * (n - 1);
// sum of arithmetic sequence again...
return n * (first_number_in_nth_row + last_number_in_nth_row) / 2;
}

Coderbyte Array Addition Solution -- For Loop with a For Loop

I'm trying to understand the logic in a solution to the Array Addition CoderByte problem. Here is the question prompt -- "Using the JavaScript language, have the function ArrayAdditionI(arr) take the array of numbers stored in arr and return the string true if any combination of numbers in the array can be added up to equal the largest number in the array, otherwise return the string false. For example: if arr contains [4, 6, 23, 10, 1, 3] the output should return true because 4 + 6 + 10 + 3 = 23. The array will not be empty, will not contain all the same elements, and may contain negative numbers."
This is a solution that works, but I get lost with the for loop within the for loop. Why isn't it always the case that i = j since the for loops both start with their counters at 0. So wouldn't it always be 0 = 0?
function ArrayAdditionI(arr) {
arr.sort(function(a,b){return a - b})
var largest = arr.pop();
var sum = 0;
for (var i = 0; i < arr.length; i++){
sum += arr[i];
for (var j = 0; j < arr.length; j++){
if (i != j) {
sum += arr[j];
if (sum == largest) {
return true;
}
}
}
for (var k = 0; k < arr.length; k++) {
if (i != k) {
sum -= arr[k];
if (sum == largest) {
return true;
}
}
}
sum = 0;
}
// code goes here
return false;
}
Thanks!
i_made_that & user3085131:
To further explain the k loop, it is used to work back through and subtract array values in the order that they were initially added, to yield new results not otherwise obtainable.
Without the k loop you can't solve many potential arrays (although it will actually pass the coderbyte test cases due to lack of appropriate test).
Consider [1,2,3,98,100]...this should pass since 2+98 = 100. However it won't without the k loop. If you log the results of sum without the k, you would see:
3 (1 + 2)
6 (3 + 3)
104 (6 + 98)
3 (2 + 1)
6 (3 + 3)
104 (6 + 98)
4 (3 + 1)
6 (4 + 2)
104 (6 + 98)
99 (98 + 1)
101 (99 + 2)
104 (101 + 3)
With the k loop however, on the second iteration of i it will pass as it will subtract 1 from 104, and then 3 from 103 to reach 100.
The thing is, is that you have 2 for loops inside the for loop with the "i" variable.
variable "i" is always going to be 0 until you finish iterating thru the 2 for loops that are inside.
for(var i=0){
for(var j=0){}
for(var k=0){}
}

Categories