So I recently discovered this site (https://projecteuler.net). The second problem asks you to find the sum of all even Fibonacci numbers less than four million. I tried to use my limited JavaScript to solve this for me, but it doesn't seem to be working at all. Here is the jsfiddle: http://jsfiddle.net/ophunt/pnf24j7q/3/
Here is the javascript contained therein:
//variables here
var sum = 0;
var fibA = 1;
var fibB = 1;
var store = 0;
//main loop
while (fibA < 4000000) {
store = fibA;
fibA += fibB;
fibB = store;
if (fibA % 2 === 0) {
sum += fibA;
}
}
Document.getElementById("result").innerHTML = sum;
So a few things can help you out here:
The sum up to fibonacci(n) = fibonacci(n+2) - 1
This is nice since you don't have to manually do the sums since you are already doing the sums when you create the sequence
Even fibonacci numbers are every third fibonacci number. This ends up meaning that the sum of the evens is equal to the sum of all divided by two.
For example:
fibs: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
sums: 1, 2, 4, 7, 12, 20, 33, 54, 88
even_sum: 0, 0, 2, 2, 2, 10, 10, 10, 44
Also give a number you can find the which fiboncacci is closest with exceeding it based on some (semi)simple math. (You can also calculate the fibonacci numbers themselves this way, but I'll leave the original function because recursive functions are cool.
The javascript implimentation looks like this:
var findFibNum = function(num) {
var est = Math.log(num * Math.sqrt(5)) /(Math.log((Math.sqrt(5)+1)/2))
return Math.floor(est)
}
Knowing these three things you can make a pretty quick solution:
var top = 4000000;
/* function finds nth fibonacci number */
var fib = function(n){
if (n <=1) return n;
return fib(n-1) + fib(n-2);
}
/* given a number this finds closest n below it i.e. for 34 it give 9
because 34 is the nineth fibonacci number
*/
var findFibNum = function(num) {
var est = Math.log(num * Math.sqrt(5)) /(Math.log((Math.sqrt(5)+1)/2))
return Math.floor(est)
}
var n = findFibNum(top) /* fib(n) is the largest fibonacci below top */
/* the sum of fibonacci number n is fib(n)+2 -1 -- this beats looping and adding*/
var fibsum = fib(n+2) -1
/* it s a nice feature of the sequence that the sum of evens is equal to the sum off all dived by 2 */
var evensum = fibsum/2
Fiddle gives 4613732
Related
I'm learning Javascript on Codecademy and have gotten stumped by a problem. I believe my issue is with the scope of my iterator tracker but not too sure.
Here are the directions given to me:
"Create a function, validateCred() that has a parameter of an array. The purpose of validateCred() is to return true when an array contains digits of a valid credit card number and false when it is invalid. This function should NOT mutate the values of the original array.
To find out if a credit card number is valid or not, use the Luhn algorithm. Generally speaking, an algorithm is a series of steps that solve a problem — the Luhn algorithm is a series of mathematical calculations used to validate certain identification numbers, e.g. credit card numbers. The calculations in the Luhn algorithm can be broken down as the following steps:
Starting from the farthest digit to the right, AKA the check digit, iterate to the left.
As you iterate to the left, every other digit is doubled (the check digit is not doubled). If the number is greater than 9 after doubling, subtract 9 from its value.
Sum up all the digits in the credit card number.
If the sum modulo 10 is 0 (if the sum divided by 10 has a remainder of 0) then the number is valid, otherwise, it’s invalid.
Here’s a visual that outlines the steps. Check your function using both the provided valid and invalid numbers."
Here's an array that should be passed into this function and return true:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
Here's an array that should return false:
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
Lastly, here's my code for trying to solve this:
function validateCred(arr) {
//Keeps track for the sum modulo later on
let totalSum = 0;
//Iterates to the left
for (let i = arr.length; i > 0; i--) {
//Keeps track of place to later double every other digit
let iterater = 1;
//Checks for every other digit and doubles it
if (iterater % 2 === 0) {
//Doubles it
let doubledAmnt = arr[i] * 2;
//Checks if doubled amount is greater than 9
if (doubledAmnt > 9) {
totalSum += (doubledAmnt - 9);
//Adds the doubled amount if not over 9
} else {
totalSum += doubledAmnt;
}
//Adds the digit if it does not need to be doubled
} else {
totalSum += arr[i];
};
//Adds to place tracker (I think my problem is here?)
iterater++
};
//Checks if the total sum is divisible by 10 to return true or false
if (totalSum % 10 === 0) {
return true;
} else {
return false;
}
}
function validateCred(arr) {
//Keeps track for the sum modulo later on
let totalSum = 0;
let iterater = 1; //iterater should be outside loop so that it wont reset in for loop
//Iterates to the left
for (let i = arr.length-1; i >= 0; i--) { //index starts in 0, so you should minus 1 to read the 16 digits
//Checks for every other digit and doubles it
if (iterater % 2 === 0) {
//Doubles it
let doubledAmnt = arr[i] * 2;
//Checks if doubled amount is greater than 9
if (doubledAmnt > 9) {
totalSum += (doubledAmnt - 9);
//Adds the doubled amount if not over 9
} else {
totalSum += doubledAmnt;
}
//Adds the digit if it does not need to be doubled
} else {
totalSum += arr[i];
};
//Adds to place tracker (I think my problem is here?)
iterater++
};
//Checks if the total sum is divisible by 10 to return true or false
if (totalSum % 10 === 0) {
return true;
} else {
return false;
}
}
Please note that indexes always start in 0 so if you start with 1, you have to minus 1 so that it will read the whole array. Next is, you put the iterater inside the loop, so it resets whenever the loop iterates, so you have to put it outside the loop. Hope this helps.
Please see the code I modified above with comments.
I'm trying to write a simple program in vanilla JavaScript for weightlifting. The user inputs a certain amount of weight and it returns the specific weight plates to put on each side of the barbell.
I then take that number into a function which subtracts 45 from it to account for the barbell weight then divides that number by 2 which is the amount of weight to put on each side of the bar.
const num = document.getElementById("weightAmount").value;
function getWeightAmount (num) {
const newNum = num - 45;
const halfNum = newNum / 2;
return getWeights(halfNum);
}
I have an array with each weight plate:
let plates = [44, 33, 22, 11, 5.5, 2.75];
I'm having trouble correctly looping through the array to get what I want. If I need, say, 60.5 lbs on each side, it should return 44, 11, 5.5. So I need to figure out which numbers in the plate array fit in the number returned from my first function.
I have an empty array called weights which I want to push the numbers from the plates array into that work with the weight which then is returned.
My question is how do I loop through the plates array to figure out which weights are needed?
A possible solution to this is iterating indefinitely until either
you have a solution
the problem becomes unsolvable given the set of weights
Every iteration step, you subtract the highest possible weight times the highest possible factor, store both in a suitable data structure (my implementation simply uses an Object) and continue.
const plates = [44, 33, 22, 11, 5.5, 2.75];
// We assume that plates is always sorted
const determineWeights = (totalWeight) => {
let factor = 0;
let weights = {};
while (totalWeight > 0) {
weight = plates.find(weight => Math.floor(totalWeight / weight) > 0);
// There is no weight we can subtract from the total weight to solve the problem
// Hence, the problem is unsolvable and we return null to indicate that no solution exists
if (!weight) { return null; }
// Determine the factor with which to multiply the weight before we subtract from the total weight an subtract the product
factor = Math.floor(totalWeight / weight);
totalWeight = totalWeight - factor * weight;
// Store weight and factor
weights[weight] = factor;
}
return weights;
}
console.log(determineWeights(104.5)); // { "11": 1, "44": 2, "5.5": 1 }
console.log(determineWeights(60.5)); // { "11": 1, "44": 1, "5.5": 1 }
console.log(determineWeights(5.0)); // null
The problem is essentially an instance of the Knapsack problem.
Note that we assume that plates is sorted. Otherwise, Array.find will not necessarily retrieve the maximum weight that can be subtracted from the total weight.
I have a simple solution below if value of the target weight will always be the sum of the available plates. Assuming the weights array are sorted in a descending order. I loop thought all available weights and will only proceed to the next weight if the total exceeds the total weight you require.
function getWeights(targeWeight) {
let plates = [44, 33, 22, 11, 5.5, 2.75];
let totalWeight = 0;
let neededPlates = [];
let i = 0;
while(i < plates.length){
var pweight = totalWeight + plates[i];
if (pweight > targeWeight) {
i++;
continue;
}
totalWeight += plates[i];
neededPlates.push(plates[i]);
}
return neededPlates;
}
console.log(getWeights(60.5)); // [44, 11, 5.5]
console.log(getWeights(104.5)); //[44, 44, 11, 5.5]
Here's a solution. In the event that the available plates don't add up to the target weight, it will return the combination of available plates that add up closest to the target. Adapted from this answer.
function createSubsets(numbers, target) {
// filter out all items larger than target
numbers = numbers.filter(function (value) {
return value <= target;
});
// sort from largest to smallest
numbers.sort(function (a, b) {
return b - a;
});
var i;
var sum = 0;
var addedIndices = [];
// go from the largest to the smallest number and
// add as many of them as long as the sum isn't above target
for (i = 0; i < numbers.length; i++) {
if (sum + numbers[i] <= target) {
sum += numbers[i];
addedIndices.push(i);
}
}
return addedIndices.map(n => numbers[n]);
}
the sum of even Fibonacci numbers below 4 mill : i am trying to do it using JavaScript, but i am getting infinity as an answer
but if i use small number such as 10, i am getting console.log() output with the result, is it possible to do that in JavaScript??
var fib = [1, 2];
for(var i =fib.length; i<4000000; i++)
{
fib[i] = fib[i-2] + fib[i-1];
}
//console.log(fib);
var arr_sum = 0;
for(var i = 0; i < fib.length; i++){
if(fib[i] % 2 === 0){
arr_sum += fib[i] ;
}
}
console.log(arr_sum);
So this is the problem:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
The correct answer is 4613732.
On the script below, the answer would be from variable "sum". I assigned it an initial value of 2 since that is the first even number on our sequence. I used 3 more variables to traverse through this sequence. The loop runs normal Fibonacci sequence and the if statement filters even numbers and adds it to the sum.
I think this is the simplest and most intuitive code implementation.
var sum = 2;
var x = 1, y = 2, fib;
while(x < 4000000) {
fib = x + y;
x = y;
y = fib;
if(fib%2===0) sum += fib;
}
console.log(sum);
Two things before I get to coding:
You need to sum the even fibonacci numbers which VALUE below 4 Million (#Alnitak)
There is an "even fibonacci series" which can be calculated in a different manner, see here.
Alright here we go:
let fib = [0, 2];
for(let i = 2; fib[i-1] < 4000000; i++) {
fib[i] = 4 * fib[i - 1] + fib[i - 2];
}
fib.pop()
let sum = fib.reduce((a, c) => a + c, 0);
console.log(sum);
Edit
Without the fib.pop() I just added, the last element of the array would be a number > 4000000. Now you should be able to get the right result.
Problem:
Bleatrix Trotter the sheep has devised a strategy that helps her fall asleep faster. First, she picks a number N. Then she starts
naming N, 2 × N, 3 × N, and so on. Whenever she names a number, she
thinks about all of the digits in that number. She keeps track of
which digits (0, 1, 2, 3, 4, 5, 6, 7, 8, and 9) she has seen at least
once so far as part of any number she has named. Once she has seen
each of the ten digits at least once, she will fall asleep.
Bleatrix must start with N and must always name (i + 1) × N directly after i × N. For example, suppose that Bleatrix picks N =
1692. She would count as follows:
N = 1692. Now she has seen the digits 1, 2, 6, and 9.
2N = 3384. Now she has seen the digits 1, 2, 3, 4, 6, 8, and 9.
3N = 5076. Now she has seen all ten digits, and falls asleep.
What is the last number that she will name before falling asleep? If she will count forever, print INSOMNIA instead.
https://code.google.com/codejam/contest/6254486/dashboard
Array.prototype.unique = function () {
return this.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
}
var uniqueArr = [];
var Number = 1692;//Any number
for (i = 1; ; i++) {
var x = Number * i;
while (x > 0) {
uniqueArr.push(x % 10); //Converting number to Digits and pushing them into an array.
x = Math.floor(x / 10);
}
var ar = uniqueArr.unique();
if (ar.length == 10) {
console.log(uniqueArr.unique(), Number * i);
break;
}
}
As long as x is always a positive number* (which is the case here) you could use
x = ~~(x / 10)
instead of
x = Math.floor(x / 10)
Which does the same job but is ~5 times faster. Its more an obvious improvement but it optimize the code anyway.
* ~~ is a bitwise operator, which just cuts off everything after the comma. So ~~-6.6 will result -6, but Math.floor(-6.6) gives you a -7. Be carefull here.
Project Euler, problem 2:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
my code so far:
var fib = [1,2];
var x = 0,
y = 1,
z = 0,
ans = 0;
while (true){
z = fib[x++] + fib[y++];
fib.push(z);
if ( !(z & 1) ) {
console.log(z + ' is even');
ans += z;
};
if(z > 4000000){
break;
}
}
console.log('answer = ' + ans);
and my console prints out:
8 is even
34 is even
144 is even
610 is even
2584 is even
10946 is even
46368 is even
196418 is even
832040 is even
3524578 is even
answer = 4613730
Does someone see the problem with my code? I've done the first 10 or so problems using Java a while back, but I don't remember having problems on this one.
As Daniel said, you're forgetting the first 2, it may be better to write your initial values as [1, 0] or use a generator like this
var fib = (function () {
var a = 1, b = 0, c = 0;
return function () {
c = a + b;
a = b;
return b = c;
};
}());
var i, t = 0;
while ((i = fib()) < 4000000) {
if ((i & 1) === 0) {
t += i;
}
}
t; // 4613732
The Fibonacci sequence actually starts 1, 1, 2, 3..
You forgot the first "2"
Maybe setting z initial to 2 helps ...
EDIT:
I was wrong!
setting ans initial to 2 helps