I have created a function that sumbs up all odd fibronacci numbers up to a given number, and for the most part it works all for except one number. For example sumFibs(10) should return 10 becuz all Fib #s <= 10 are 1,1,3 and 5.
If I do sumFibs(75024); I get 135721 instead of the expected value is 60696. For every other number it works perfectly and am scratching my head to solve it
function sumFibs(num) {
let thunderAss = [];
let currDmp = 0;
let nxtRmp = 1;
var pushNxt = 0;
// push into array
for (let x = 0; x < num; x++) {
if (x <= 1) {
console.log("lets go");
thunderAss.push(1); // 2l almond milk
} else {
thunderAss.push(thunderAss[x - 1] + thunderAss[x - 2]);
console.log(x, " x is factor");
}
}
console.log(thunderAss);
let cuntNuts = 0;
for (let x = 0; x < num; x++) {
if (cuntNuts < num) {
if (thunderAss[x] % 2 == 0) {} else {
cuntNuts += thunderAss[x];
}
} else {
break;
}
}
console.log("CN: ", cuntNuts);
return cuntNuts;
}
sumFibs(75024); // 60696 but 135721
sumFibs(4);
The condition if (cuntNuts < num) is wrong. cuntNuts is the sum of fibonacci numbers, not the fibonacci number itself. So you're stopping when the sum reaches n, not summing all the odd numbers up to n.
You should be comparing thunderAss[x] with num. And it should be <= if that number should be included in the total.
You can also put this condition into the for loop header rather than adding it as a separate check in the body.
function sumFibs(num) {
let thunderAss = [];
let currDmp = 0;
let nxtRmp = 1;
var pushNxt = 0;
// push into array
for (let x = 0; x < num; x++) {
if (x <= 1) {
console.log("lets go");
thunderAss.push(1); // 2l almond milk
} else {
thunderAss.push(thunderAss[x - 1] + thunderAss[x - 2]);
console.log(x, " x is factor");
}
}
console.log(thunderAss);
let cuntNuts = 0;
for (let x = 0; thunderAss[x] <= num; x++) {
if (thunderAss[x] % 2 == 0) {} else {
cuntNuts += thunderAss[x];
}
}
console.log("CN: ", cuntNuts);
return cuntNuts;
}
sumFibs(75024); // 60696 but 135721
sumFibs(4);
You are adding the num first Fibonacci numbers instead of the Fibonacci numbers less than or equal to num.
In my solution here, I do the correct thing and get the correct answer:
function* fibonacci()
{
let x = 0;
let y = 1;
while (true) {
yield x;
[x, y] = [y, x+y];
}
}
function sum_odd_fibonacci(max)
{
const fib_seq = fibonacci();
let s = 0;
let n;
while ( (n=fib_seq.next().value) <= max) {
if (n % 2 == 1) {
s += n;
}
}
return s;
}
console.log(sum_odd_fibonacci(75024));
Related
I've been trying to solve this kata on codewars.
I've got an algorithm, but it's apparently too slow to pass the test. It can create sequence of 2450 numbers in just under 1.6 seconds. I don't need the solution but the hint or something to help me to make my algorithm faster.
function ulamSequence(u0, u1, n) {
// create an array with first two elements in it
const seq = [u0, u1];
// create a loop that checks if next number is valid and if it is, push it in seq
num: for (let i = u1 + 1; seq.length < n; i++) {
let sumCount = 0;
for (let k = 0; k < seq.length - 1; k++) {
if (seq.indexOf(i - seq[k]) > k && ++sumCount === 2) { continue num; }
}
sumCount === 1 ? seq.push(i) : "";
}
return seq;
}
Here's an idea: have an array sums so that sums[N] keeps the number of possible summations for N. For example, for U(1,2) sums[3] will be 1 and sums[5] will be 2 (1+4, 2+3). On each step, locate the minimal N so that N > last item and sums[N] == 1. Add N to the result, then sum it with all previous items and update sums accordingly.
function ulam(u0, u1, len) {
let seq = [u0, u1]
let sums = []
let last = u1
sums[u0 + u1] = 1
while (seq.length < len) {
last += 1
while (sums[last] !== 1) {
last += 1
}
for (let n of seq) {
let s = n + last
sums[s] = (sums[s] || 0) + 1
}
seq.push(last)
}
return seq
}
console.time()
ulam(1, 2, 2450)
console.timeEnd()
function ulamSequence(u0, u1, n) {
const seq = [u0, u1];
const set = new Set(seq);
for (let i = u1 + 2; seq.length < n; i++) {
let sumCount = 0;
for (let k = 0; k < seq.length - 1; k++) {
if (set.has(i - seq[k])) {
sumCount++;
if (sumCount === 2) {
continue;
}
}
}
if (sumCount === 1) {
seq.push(i);
set.add(i);
}
}
return seq;
}
I was looking for an answer for a question from Project Euler and I found one here
http://www.mathblog.dk/triangle-number-with-more-than-500-divisors/
int number = 0;
int i = 1;
while(NumberOfDivisors(number) < 500){
number += i;
i++;
}
private int NumberOfDivisors(int number) {
int nod = 0;
int sqrt = (int) Math.Sqrt(number);
for(int i = 1; i<= sqrt; i++){
if(number % i == 0){
nod += 2;
}
}
//Correction if the number is a perfect square
if (sqrt * sqrt == number) {
nod--;
}
return nod;
}
So I tried to implement the same solution in Javascript but it doesn't give me the same result.
var number = 0;
var i = 1;
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.sqrt(num);
for (i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
I tested the other code in C# and it gives the right solution. I was wondering if I made a mistake or whether they work differently in some aspect I'm unaware of.
The problem is that you are testing non-triangle numbers because you forgot one important thing ... scope ...
for (i = 1; i <= sqr; i++) {
screws your (global) value of i ...
see in c# you have
for(int i = 1; i<= sqrt; i++){
^^^
give javascript the same courtesy and try
for (var i = 1; i <= sqr; i++) {
^^^
you should also get the square root as an integer, otherwise you'll be one off in most counts
var sqr = Math.floor(Math.sqrt(num));
i.e.
var number = 0;
var i = 1;
console.time('took');
while (numberOfDivisors(number) < 500) {
number += i;
i++;
}
console.timeEnd('took');
console.log(number);
function numberOfDivisors(num) {
var nod = 0;
var sqr = Math.floor(Math.sqrt(num));
for (var i = 1; i <= sqr; i++) {
if (num % i === 0) {
nod += 2;
}
}
if (sqr * sqr == num) {
nod--;
}
return nod;
}
(added some timing info for fun)
https://codepen.io/aholston/pen/ZJbrjd
The codepen link has commented code as well as actual instructions in HTML
Otherwise.... what I ultimately have to do is write a function that takes two params(a and b) and takes all the numbers between those two params (a-b) and put every number that can be added to the consecutive fowers and be equal to that number into a new array. Ex: 89 = 8^1 + 9^2 = 89 or 135 = 1^1 + 3^2 + 5^3 = 135
function sumDigPow(a, b) {
// Your code here
var numbers = [];
var checkNum = [];
var finalNum = [];
var total = 0;
for (var i = 1; i <= b; i++) {
if (i >= a && i <= b) {
numbers.push(i);
}
}
for (var x = 0; x < numbers.length; x++) {
var checkNum = numbers[x].toString().split('');
if (checkNum.length == 1) {
var together = parseInt(checkNum);
finalNum.push(together);
} else if (checkNum.length > 1) {
var together = checkNum.join('');
var togNumber = parseInt(together);
for (var y = checkNum.length; y > 0; y--) {
total += Math.pow(checkNum[y - 1], y);
}
if (total == togNumber) {
finalNum.push(togNumber);
}
}
}
return finalNum;
}
try this:
function listnum(a, b) {
var finalNum = [];
for (var i = a; i <= b; i++) {
var x = i;
var y = i;
var tot = 0;
j = i.toString().length;
while (y) {
tot += Math.pow((y%10), j--);
y = Math.floor(y/10);
}
if (tot == x)
finalNum.push(i);
}
return finalNum;
}
console.log(listnum(1, 200));
Okay, after debugging this is what I learned.
for (var y = checkNum.length; y > 0; y--) {
total += Math.pow(checkNum[y - 1], y);
}
if (total == togNumber) {
finalNum.push(togNumber);
}
}
}
return finalNum;
}
Everytime this loop happened, I neglected to reset the 'total' variable back to 0. So I was never getting the right answer for my Math.pow() because my answer was always adding to the previous value of total. In order to fix this, I added var total = 0; after i decided whether or not to push 'togNumber' into 'finalNum.' So my code looks like this..
for (var y = checkNum.length; y > 0; y--) {
total += Math.pow(checkNum[y - 1], y);
}
if (total == togNumber) {
finalNum.push(togNumber);}
}
var total = 0;
}
return finalNum;
}
I am trying this code
var sum = 0
for (i = 0; i < 2000000; i++) {
function checkIfPrime() {
for (factor = 2; factor < i; factor++) {
if (i % factor = 0) {
sum = sum;
}
else {
sum += factor;
}
}
}
}
document.write(sum);
I am getting this error:
Invalid left-hand side in assignment
Change if(i % factor = 0) to if( i % factor == 0) and remove the function checkIfPrime() inside the for loop.
var sum = 0
for (i = 0; i < 2000000; i++) {
for (factor = 2; factor < i; factor++) {
if (i % factor == 0) {
sum = sum;
}
else {
sum += factor;
}
}
}
document.write(sum);
The function inside the loop is pointless.
it looks like your code outputs wrong result, for example prime numbers below 6 are 2, 3 and 5, their sum is 10, your code outputs 14 in this case.
Here is another code which outputs sum of primes below max value:
var sieve = [], primes = [], sum = 0, max = 5;
for (var i = 2; i <= max; ++i) {
if (!sieve[i]) {
// i has not been marked -- it is prime
sum += i;
for (var j = i << 1; j <= max; j += i) {
sieve[j] = true;
}
}
}
console.log(sum);
credit to How to find prime numbers between 0 - 100?
function sumPrimes(num) {
var sum = 0;
for (var i = 2; i < num; i++) {
if (isPrime(i)) {
sum += i;
console.log(sum);
}
}
return sum;
}
function isPrime(num) {
if (num <= 1) return false;
else if (num <= 3) return true;
else if (num % 2 == 0 || num % 3 == 0) return false;
var i = 5;
while (i * i <= num) {
if (num % i == 0 || num % (i + 2) == 0) return false;
i += 6;
}
return true
}
console.log(sumPrimes(2000000));
Well, I did with 250 otherwise my screen would have frozen. First of you have to single out the prime numbers after placing them inside an empty Array, which I called primeNumbers from 2 to whatever number you want. Then I create a function that would filter the prime numbers and then add them all with a reduce method inside of another variable called sum and return that variable.
var primeNumbers =[];
for(var i = 2; i < 250; i++){
primeNumbers.push(i);
}//for loop
function isPrime(value){
for(var x=2; x< value; x++){
if(value % x===0){
return false;
}
}//for loop
return true;
}//function isPrime to filter
var sum = primeNumbers.filter(isPrime).reduce(function(acc, val) {
return acc + val;
}, 0);
console.log(sum);
when you are using a variable inside the loop you need to declare them. You have two points in this case
i is not declared
factor is not declare
Your if (i % factor = 0) is wrong, as pointed by some people above.
Also, you never call the checkIfPrime() method. I don't why you created them. Also, I improved your checkIfPrime() method. Please call sumOfPrimes() method in the code below and it should work. You can modify it according to your need
function sumOfPrimes()
{
var sum =0;
for (var i = 0; i < 2000000; i++)
{
var temp = Math.sqrt(i);
for (var factor = 2; factor < temp; factor++)
{
if (i % factor === 0)
{
sum += factor;
}
}
}
console.log(sum);
}
Try changing this line if (i % factor = 0) {
to
if (i % factor == 0) {
My results for numbers between 1 and 28321 (limit)
sum of all numbers: 395465626
sum of all abundant numbers: 392188885
sum of all non abundant numbers: 3276741 (correct answer is 4179871)
var divisors = function(number){
sqrtNumber = Math.sqrt(number);
var sum = 1;
for(var i = 2; i<= sqrtNumber; i++)
{
if (number == sqrtNumber * sqrtNumber)
{
sum += sqrtNumber;
sqrtNumber--;
}
if( number % i == 0 )
{
sum += i + (number/i);
}
}
if (sum > number) {return true;}
else {return false;}
};
var abundent = [], k = 0;
var upperLimit = 28123;
for (var i = 1; i <= upperLimit; i++)
{
if (divisors(i))
{abundent[k] = i; k++};
}
var abundentCount = abundent.length;
var canBeWrittenAsAbundant = [];
for (var i = 0; i < abundentCount; i++){
for (var j = i; j < abundentCount; j++){
if (abundent[i] + abundent[j] <= upperLimit){canBeWrittenAsAbundant[abundent[i]+abundent[j]] = true;}
else {
break;
}
}
}
for (i=1; i <= upperLimit; i++){
if (canBeWrittenAsAbundant[i] == true){continue;}
else {canBeWrittenAsAbundant[i] = false;}
}
var sum = 0;
for (i=1; i <= upperLimit; i++)
{
if (!canBeWrittenAsAbundant[i]){
sum += i;
}
}
console.log(sum);
I'm using http://www.mathblog.dk/project-euler-23-find-positive-integers-not-sum-of-abundant-numbers/ as guidance, but my results are different. I'm a pretty big newb in the programming community so please keep that in mind.
You do not need to calculate the sum of all numbers using a cycle, since there is a formula, like this:
1 + 2 + ... + number = (number * (number + 1)) / 2
Next, let's take a look at divisors:
var divisors = function(number){
sqrtNumber = Math.sqrt(number);
var sum = 1;
for(var i = 2; i<= sqrtNumber; i++)
{
if (number == sqrtNumber * sqrtNumber)
{
sum += sqrtNumber;
sqrtNumber--;
}
if( number % i == 0 )
{
sum += i + (number/i);
}
}
if (sum > number) {return true;}
else {return false;}
};
You initialize sum with 1, since it is a divisor. However, I do not quite understand why do you iterate until the square root instead of the half of the number. For example, if you call the function for 100, then you are iterating until i reaches 10. However, 100 is divisible with 20 for example. Aside of that, your function is not optimal. You should return true as soon as you found out that the number is abundant. Also, the name of divisors is misleading, you should name your function with a more significant name, like isAbundant. Finally, I do not understand why do you decrease square root if number happens to be its exact square and if you do so, why do you have this check in the cycle. Implementation:
var isAbundant = function(number) {
var sum = 1;
var half = number / 2;
for (var i = 2; i <= half; i++) {
if (number % i === 0) {
sum += i;
if (sum > number) {
return true;
}
}
}
return false;
}
Note, that perfect numbers are not considered to be abundant by the function.
You do not need to store all numbers, since you are calculating aggregate data. Instead, do it like this:
//we assume that number has been initialized
console.log("Sum of all numbers: " + ((number * (number + 1)) / 2));
var abundantSum = 0;
var nonAbundantSum = 0;
for (var i = 0; i <= number) {
if (isAbundant(i)) {
abundantSum += i;
} else {
nonAbundantSum += i;
}
}
console.log("Sum of non abundant numbers: " + nonAbundantSum);
console.log("Sum of abundant numbers: " + abundantSum);
Code is not tested. Also, beware overflow problems and structure your code.
Below is the Corrected Code for NodeJS..
var divisors = function (number) {
sqrtNumber = Math.sqrt(number);
var sum = 1;
var half = number / 2;
for (var i = 2; i <= half; i++) {
if (number % i === 0) { sum += i; }
}
if (sum > number) { return true; }
else { return false; }
};
var abundent = [], k = 0;
var upperLimit = 28123;
for (var i = 1; i <= upperLimit; i++) {
if (divisors(i)) { abundent[k] = i; k++ };
}
var abundentCount = abundent.length;
var canBeWrittenAsAbundant = [];
for (var i = 0; i < abundentCount; i++) {
for (var j = i; j < abundentCount; j++) {
if (abundent[i] + abundent[j] <= upperLimit) { canBeWrittenAsAbundant[abundent[i] + abundent[j]] = true; }
else {
break;
}
}
}
for (i = 1; i <= upperLimit; i++) {
if (canBeWrittenAsAbundant[i] == true) { continue; }
else { canBeWrittenAsAbundant[i] = false; }
}
var sum = 0;
for (i = 1; i <= upperLimit; i++) {
if (!canBeWrittenAsAbundant[i]) {
sum += i;
}
}
console.log(sum);