Project Euler Q#2 in "javascript" - javascript

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.

Related

Alternate numbers into two rows

I think I'm having a brain fart, because I can't figure out a simple formula to be able sort a sequence of number into specific order so it can be printed 2 numbers per sheet of paper (one number on one half and second number on second half), so when the printed stack of paper cut in half, separating the numbers, and then these halves put together, the numbers would be in sequence.
So, let's say I have 5 numbers: 3,4,5,6,7, the expected result would be 3,6,4,7,5 or
0,1,2,3,4,5,6,7 would become 0,4,1,5,2,6,3,7
My thought process is:
create a loop from 0 to total number of numbers
if current step is even, then add to it total numbers divided in 2
Obviously, I'm missing a step or two here, or there is a simple mathematical formula for this and hopefully someone could nudge me in a right direction.
This is what I have so far, it doesn't work properly if start number set to 1 or 3
function show()
{
console.clear();
for(let i = 0, count = end.value - start.value, half = Math.round(count/2); i <= count; i++)
{
let result = Math.round((+start.value + i) / 2);
if (i && i % 2)
result = result + half -1;
console.log(i, "result:", result);
}
}
//ignore below
for(let i = 0; i < 16; i++)
{
const o = document.createElement("option");
o.value = i;
o.label = i;
start.add(o);
end.add(o.cloneNode(true));
}
start.value = 0;
end.value = 7;
function change(el)
{
if (+start.value > +end.value)
{
if (el === start)
end.value = start.value;
else
start.value = end.value;
}
}
<select id="start" oninput="change(this)"></select> -
<select id="end" oninput="change(this)"></select>
<button onclick="show()">print</button>
P.S. Sorry, about the title, couldn't come up with anything better to summarize this.
You could get the value form the index
if odd by using the length and index shifted by one to rigth (like division by two and get the integer value), or
if even by the index divided by two.
function order(array) {
return array.map((_, i, a) => a[(i % 2 * a.length + i) >> 1]);
}
console.log(...order([3, 4, 5, 6, 7]));
console.log(...order([0, 1, 2, 3, 4, 5, 6, 7]));

Having trouble with the Fibonacci Sequence

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

Project Euler - Trying to better my Javascript through P.E., Stuck on number 2

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

Finding the nth item in a repeating list of fixed items

I have to determine the mathematical formula to calculate a particular repeating position in a series of numbers. The list of numbers repeats ad infinitum and I need to find the number every n numbers in this list. So I want to find the *n*th item in a list of repeating y numbers.
For example, if my list has 7 digits (y=7) and I need every 5th item (n=5), how do I find that item?
The list would be like this (which I've grouped in fives for ease of viewing):
12345 67123 45671 23456 71234 56712 34567
I need to find in the first grouping number 5, then in the second grouping number 3, then 1 from the third group, then 6, then 4, then 2, then 7.
This needs to work for any number for y and n. I usually use a modulus for finding *n*th items, but only when the list keeps increasing in number and not resetting.
I'm trying to do this in Javascript or JQuery as it's a browser based problem, but I'm not very mathematical so I'm struggling to solve it.
Thanks!
Edit: I'm looking for a mathematical solution to this ideally but I'll explain a little more about the problem, but it may just add confusion. I have a list of items in a carousel arrangement. In my example there are 7 unique items (it could be any number), but the list in real terms is actually five times that size (nothing to do with the groups of 5 above) with four sets of duplicates that I create.
To give the illusion of scrolling to infinity, the list position is reset on the 'last' page (there are two pages in this example as items 1-7 span across the 5 item wide viewport). Those groups above represent pages as there are 5 items per page in my example. The duplicates provide the padding necessary to fill in any blank spaces that may occur when moving to the next page of items (page 2 for instance starts with 6 and 7 but then would be empty if it weren't for the duplicated 1,2 and 3). When the page goes past the last page (so if we try to go to page 3) then I reposition them further back in the list to page one, but offset so it looks like they are still going forwards forever.
This is why I can't use an array index and why it would be useful to have a mathematical solution. I realise there are carousels out there that do similar tasks to what I'm trying to achieve, but I have to use the one I've got!
Just loop every 5 characters, like so:
var data = "12345671234567123456712345671234567";
var results = [];
for(var i = 4; i < data.length; i += 5){
results.push(data[i]);
}
//results = [5, 3, 1, 6, 4, 2, 7]
If you want to use a variable x = 5; then your for loop would look like this:
for(var i = x - 1; i < data.length; i += x){...
There is no need to know y
If your input sequence doesn't terminate, then outputting every nth item will eventually produce its own repeating sequence. The period (length) of this repetition will be the lowest common multiple of the period of the input sequence (y) and the step size used for outputting its items (x).
If you want to output only the first repetition, then something like this should do the trick (untested):
var sequence = "1234567";
var x = 5;
var y = sequence.length;
var count = lcm(x, y);
var offset = 4;
var output = [];
for (var i = 0; i < count; i += x)
{
j = (offset + i) % y;
output.push(sequence[j]);
}
You should be able to find an algorithm for computing the LCM of two integers fairly easily.
A purely mathematical definition? Err..
T(n) = T(n-1) + K For all n > 0.
T(1) = K // If user wants the first element in the series, you return the Kth element.
T(0) = 0 // If the user want's a non-existent element, they get 0.
Where K denotes the interval.
n denotes the desired term.
T() denotes the function that generates the list.
Lets assume we want every Kth element.
T(1) = T(0) + K = K
T(2) = T(1) + K = 2K
T(3) = T(2) + K = 3K
T(n) = nk. // This looks like a promising equation. Let's prove it:
So n is any n > 1. The next step in the equation is n+1, so we need to prove that
T(n + 1) = k(n + 1).
So let's have a go.
T(n+1) = T(N+1-1) + K.
T(n+1) = T(n) + K
Assume that T(n) = nk.
T(n+1) = nk + k
T(n+1) = k(n + 1).
And there is your proof, by induction, that T(n) = nk.
That is about as mathematical as you're gonna get on SO.
Nice simple recurrence relation that describes it quite well there.
After your edit I make another solution;)
var n = 5, y = 7;
for (var i = 1; i<=y; i++) {
var offset = ( i*y - (i-1)*n ) % y;
var result = 0;
if (offset === n) {
result = y;
} else {
result = (n - offset) > 0 ? n - offset : offset;
}
console.log(result);
}
[5, 3, 1, 6, 4, 2, 7] in output.
JSFIDDLE: http://jsfiddle.net/mcrLQ/4/
function get(x, A, B) {
var r = (x * A) % B;
return r ? r : B;
}
var A = 5;
var B = 7;
var C = [];
for (var x = 1; x <= B; ++x) {
C.push(get(x, A, B));
}
console.log(C);
Result: [5, 3, 1, 6, 4, 2, 7]
http://jsfiddle.net/xRFTD/
var data = "12345 67123 45671 23456 71234 56712 34567";
var x = 5;
var y = 7;
var results = [];
var i = x - 1; // enumeration in string starts from zero
while ( i <= data.length){
results.push(data[i]);
i = i + x + 1;// +1 for spaces ignoring
}

Why isn't my attempted solution working?

When I run the code in the console, the browser just stops working (am assuming stack overflow).
I've come up with several different algorithms for solving this problem, but I thought this one would not cause any SOs.
The problem:
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1 3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
Failing solution:
function divisors(n){
var counter = 0;
var triangle = 3;
var triangle_add = 2;
while (counter < n){
for (var i = 1; i = triangle; i++){
if (triangle % i === 0){
counter++;
}
};
if (counter < n){
triangle_add++;
triangle = triangle + triangle_add;
counter = 0;
};
};
return triangle;
};
console.log(divisors(501));
Your solution is not working because, most probably, it is very slow. This problem can be solved much faster by the following method:
Find all the prime numbers smaller than some N (put, for example, N=100'000) using Sieve of Eratosthenes. It is quite fast.
As we know from elementary math each number can be written in the form X=p1^i1*p2^i2*...*pn^in where pj is prime number and ij is the power of corresponding prime number. The number of divisors of X is equal to (i1+1)*(i2+1)*...*(in+1) since that many different ways we can form a number which will be divisor of X. Having an array of prime numbers the number of divisors for X can be calculated quite fast (the code still has place to be optimized):
int divisorCount(long long X)
{
int c = 1;
for (int i = 0; PRIMES[i] <= X; ++i)
{
int pr = PRIMES[i];
if (X % pr == 0)
{
int p = 1;
long long r = X;
while (r % pr == 0)
{
r = r / pr;
++p;
}
c *= p;
}
}
return c;
}
Iterate through all triangle numbers and count divisor numbers for them using the above function. The i-th triangle number is i * (i + 1) / 2, so no need to keep a variable, increment it and add it each time.

Categories