Increasing the speed of this algorithm - c++

I'm trying to make this code run faster, and I am having trouble doing so. I can pass most of my test cases, but as the numbers get larger I cant pass them.
Input: 92871036442 3363728910382456 output: 1160053175781729
Input: 1 1000000000000000000 output: 264160473575034274
These test cases won't pass. What can I do to speed up my algorithm and prevent it from timing out?
#include<iostream>
using namespace std;
bool isLuckyNumber(unsigned long long n)
{
bool found6 = false, found8 = false;
while (n > 0)
{
int digit = n % 10;
if (digit == 6)
{
found6 = true;
}
else if (digit == 8)
{
found8 = true;
}
//removing last digit
n = n / 10;
}
if (found6 && found8)
{
return false;
}
//otherwise if any one of them is true, it is a lucky number
else if (found6 || found8)
{
return true;
}
//otherwise not a lucky number
return false;
}
int main()
{
//creating needed variables, using unsigned long long as data type as it
//can store huge values (between 0 and 18446744073709551615)
unsigned long long L, R, count = 0;
//reading L and R
cin >> L >> R;
//looping as long as L<=R
while (L <= R)
{
//if L is lucky number, incrementing count
if (isLuckyNumber(L))
{
count++;
}
//incrementing L
L++;
}
//displaying count at the end
cout << count << endl;
return 0;
}

Consider the numbers in range 0 - 10n-1, they are the combinations with repetitions of the 10 digits.
The number of combinations without a specified digit is 9n, if you want to exclude two digits is 8n.
Lucky numbers are defined as the set of combinations containing either 6 or 8 but not both. Using basic set theory we can extract some formulas.
N is the total range with cardinality |N| = 10n
N-6, N-8 are the set of number not containing 6 or 8, |N-6| = |N-8| = 9n
N-68, numbers containing neither 6 nor 8, |N-68| = 8n.
From this we can calculate all cardinalities:
|N+6| = |N| - |N-6|
|N+8| = |N| - |N-8|
|N+6| + |N+8| - |N+68| + |N-68| = |N|
|LUCKY| = |N+6| + |N+8| - |N+68| *2 = 2 * ( 9n - 8n )
Now, we need to know the lucky number in a range that is not a power of 10, then we have to split our input in several blocks, each block with the form J * 10^K - (J+1) * 10^K - 1.
The number of such blocks is linear in the input size, that is no more than 10 * [digits of [number + 1]], so the total cost of the algorithm is also linear in the input size, that is log(n) where n is the greatest number in input.
When calculating each block we must take into account J, the prefix:
if J contains both 6 and 8 we can skip the block since the number is
not lucky
if J contains either 6 or 8 but not both, then the formula for this block is |N-8| or |N-6| = 9^K
in the remaining case the formula is 9^K - 8^K.
So, in total:
add 1 to your input numbers since the algorithm exclude the upper bound of the range
slice your number in blocks
calculate the lucky numbers and for each input number, then subtract them to find the result
To do a quick check consider the case where you have the range 1 to 1000000000000000000 (18 digits), since 1 and 1000000000000000000 are not lucky you can directly apply the formula 2 * ( 918 - 8 18 ).
Code:
#include <iostream>
using namespace std;
long countLucky(long number) {
//Algorithm excludes upper bound, so increase it by to include
number++;
long ncopy=number;
//Count digits
int size=0;
while (ncopy>0) {
ncopy/=10;
size++;
}
ncopy=number;
//Extract digits into array
int digits[size];
for (int d=0;ncopy>0;d++) {
digits[d]=ncopy%10;
ncopy/=10;
}
//Calculate powers of 10, 9, 8 starting with size-1
long pow10=1;
long pow9=1;
long pow8=1;
for (int i=0;i<size-1;i++) {
pow10*=10;
pow9*=9;
pow8*=8;
}
bool prefix6=false;
bool prefix8=false;
long count=0;
for (int d=size-1;d>=0;d--) {
//Both digits present in prefix, so no more lucky numbers can be found
if (prefix6 && prefix8) {
break;
}
for (int block=0;block<digits[d];block++) {
if ((prefix6 || (block==6)) && (prefix8 || (block==8))) {
continue;
}
if ((prefix6 || (block==6)) || (prefix8 || (block==8))) {
count+=pow9;
} else {
count+=2*(pow9-pow8);
}
}
//Calculate new powers
pow10/=10;
pow9/=9;
pow8/=8;
//Update prefix status
prefix6 = prefix6 || (digits[d]==6);
prefix8 = prefix8 || (digits[d]==8);
}
cout << endl;
return count;
}
int main() {
long c=countLucky(3363728910382456)-countLucky(92871036442);
cout << "Result " << c << endl;
cout << "Solution " << 1160053175781729 << endl;
}

The idea here is not to test each numbers in that range, but instead you should be finding the answer through number theory.
A way to find the answer, is to first find all the numbers in a range that has the number 6, then find all the numbers in that same range that has the number 8 in it. Then you minus the numbers that have both of them.
Below I have a piece of code that just count the lucky number from any 10^n (which includes 10^0, or 1) to any 10^m:
unsigned long long luckyCount(unsigned long long N)
{
for(auto tempN = N; tempN != 1; tempN /= 10) if(tempN % 10) throw;
// Just some error check, so you can't input any number other than 10^n
unsigned long long T = 0, D = 0, C = 0;
while(N /= 10)
{
D = D * 8 + T * 2;
T = T * 9 + std::pow(10, C);
++C;
}
return T * 2 - D * 2;
}
unsigned long long luckyCount(unsigned long long L, unsigned long long R)
{
return luckyCount(R) - luckyCount(L);
}
int main()
{
unsigned long long L, R;
cin >> L >> R;
std::cout << luckyCount(L, R) << "\n";
}
For each iteration, the amount of number that have a 6 in it and a 8 in it are the same, and both of them are denoted as T. And the amount of numbers that have both 6 and 8 in it are denoted as D.
Hopefully this will give you a starting point, and you algorithm will be running at O(log(N)).

I won't give you a complete algorithm, but just a starting point.
How many lucky numbers are there between 1 and 100?
All the ones in the form 6x + the ones like x6 + 1 (66) + all the 8x + all the x8 + 1 (88), where x can be 0, 1, 2, 3, 4, 5, 7, 9. So there are
(8 + 8 + 1) * 2 = 34 lucky numbers (*).
How many lucky numbers are between a and b?
The ones between 1 and b minus the ones between a and 1.
keep up the reasoning and you'll end up with an algorithm with a complexity better than O(n).
(*) Which are: 6, 8, 16, 18, 26, 28, 36, 38, 46, 48, 56, 58, 60, 61, 62, 63, 64, 65, 66, 67, 69, 76, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 96, 98.

Related

Sequence of n numbers - compute all possible k-subsequence of "lucky" numbers

I have a problem with one task, so if you could help me a little bit.
Numbers are "lucky" or "unlucky". Number is "lucky" just if every
digit 7
or every digit is 4. So "lucky" numbers are for example 4, 44, 7, 77.
"Unlucky" are the others numbers.
You will get sequence of n-elements and number K. Your task is to
compute number of all possible k-elements subsequence, which fulfill a one
condition. The condition is that in the subsequence mustn't be two same "lucky"
numbers. So for example there mustn't 77 and 77...
Output number of all possible k-elements subsequence mod 10^9+7
0 < N,K < 10^5
Few examples:
Input:
5 2
7 7 3 7 77
Output:
7
Input:
5 3
3 7 77 7 77
Output:
4
Input:
34 17
14 14 14 ... 14 14 14
Output:
333606206
I have code which seems to work, but it is too slow when I try to compute binomial coefficient. I'm using map. In string I store number in string format. In second - int - part of the map is number which represents how many times was that number(in the first map parameter) used. So now I have stored every "unlucky" numbers stored together. Also every same "lucky" number is together. When I have it stored like this, I just compute all multiplications. For example:
Input
5 2
3 7 7 77 7
Are stored like this: map["other"] = 1 map["7"] = 3 map["77"] = 1
Because k = 2 --> result is: 1*3 + 1*1 + 1*3 = 7.
I think problem is with computing binomial coefficient. For the third example it needs to compute (34 choose 17) and it is computing very long time.I've found this article and also this , but I don't understand how they are solving this problem.
My code:
#include<iostream>
#include<string>
#include<map>
#include <algorithm>
#include <vector>
using namespace std;
int binomialCoeff(int n, int k)
{
// Base Cases
if (k == 0 || k == n)
return 1;
// Recur
return binomialCoeff(n - 1, k - 1) + binomialCoeff(n - 1, k);
}
int main()
{
int n, k;
cin >> n >> k;
map<string, int> mapa; // create map, string is a number, int represents number of used string-stored numbers ---> so if 7 was used two times, in the map it will be stored like this mapa["7"] == 2 and so on)
for (int i = 0; i < n; i++) // I will load number as string, if this number is "lucky" - digist are all 7 or all 4
{ // every "unlucky" numbers are together, as well as all same "lucky" numbers ---> so 77 and 77 will be stored in one element....
string number;
cin >> number;
char digit = number[0];
bool lucky = false;
if (digit == '7' || digit == '4')
lucky = true;
for (int j = 1; j < number.length(); j++) {
if (digit != '7' && digit != '4')
break;
if (number[j] != digit) {
lucky = false;
break;
}
}
if (lucky)
mapa[number]++;
else
mapa["other"]++;
}
vector<bool> v(mapa.size());
bool lack = k > mapa.size(); //lack of elements in map --> it is when mapa.size() < k; i. e. number of elements in array can't make k-element subsequence.
int rest = lack ? k - mapa.size() + 1 : 1; // how many elements from "unlucky" numbers I must choose, so it makes base for binomial coefficient (n choose rest)
if (lack) //if lack is true, different size of vector
fill(v.begin() + mapa.size(), v.end(), true);
else
fill(v.begin() + k, v.end(), true);
int *array = new int[mapa.size()]; //easier to manipulate with array for me
int sum = 0;
int product = 1;
int index = 0;
for (map<string, int> ::iterator pos = mapa.begin(); pos != mapa.end(); ++pos) // create array from map
{
if (lack && pos->first == "other") { //if lack of elements in map, the number in elemets representing "unlucky" numbers will be binomial coefficient (mapa["other] choose rest)
array[index++] = binomialCoeff(mapa["other"], rest);
continue;
}
array[index++] = pos->second;
}
do { // this will create every posible multiplication for k-elements subsequences
product = 1;
for (int i = 0; i < mapa.size(); ++i) {
if (!v[i]) {
product *= array[i];
}
}
sum += product;
} while (next_permutation(v.begin(), v.end()));
if (mapa["other"] >= k && mapa.size() > 1) { // if number of "unlucky" numbers is bigger than k, we need to compute all possible k-elements subsequences just from "unlucky" number, so binomial coefficient (mapa["other] choose k)
sum += binomialCoeff(mapa["other"], k);
}
cout << sum % 1000000007 << endl;
}

Fast way to find a unhappy number

I'm trying to solve a question. Given a range of integers user has to find the number of unhappy present in the given range.
Unhappy number- a number n such that iterating this sum-of-squared-digits map starting with n never reaches the number 1.
I've tried using the brute force approach by calculating the sum of the squares of digits and if at any instant it is equal to any of these (4, 16, 37, 58, 89, 145, 42, 20) then it is a unhappy number.
This approach is giving TLE is there any better method??
Range is between 1 to 10^18.
Your range is between 1 and 1018. This means your numbers have a maximum of 18 digits.
Consider that the maximum square of a digit is 92 = 81, after doing the squared-digit-sum once the maximum number is 18 * 81 = 1458.
So one squared-digit-sum plus a lookup table of ~1500 elements should suffice.
Or two squared-digit-sums plus a lookup table of ~330 elements:
static const bool unhappy[330] {
1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,
1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,
1,1,1,0,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,
0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,
1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,0,0,1,
1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,0
}
inline bool is_unhappy(uint64_t n) {
while (n >= 330) {
int r = 0;
while (n > 0) {
int d = n % 10;
r += d*d;
n /= 10;
}
n = r;
}
return unhappy[n];
}
#include <map>
#include <set>
bool happy(int number) {
static std::map<int, bool> cache;
std::set<int> cycle;
while (number != 1 && !cycle.count(number)) {
if (cache.count(number)) {
number = cache[number] ? 1 : 0;
break;
}
cycle.insert(number);
int newnumber = 0;
while (number > 0) {
int digit = number % 10;
newnumber += digit * digit;
number /= 10;
}
number = newnumber;
}
bool happiness = number == 1;
for (std::set<int>::const_iterator it = cycle.begin();
it != cycle.end(); it++)
cache[*it] = happiness;
return happiness;
}
#include <iostream>
int main() {
for (int i = 1; i < 10; i++)
if (!happy(i))
std::cout << i << std::endl;
return 0;
}
Output:
2
3
4
5
6
8
9
Logic and most of the code taken from here: https://tfetimes.com/c-happy-numbers/

fibbonacci sequence even term sum?

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.
#include <iostream>
using namespace std;
int main() {
int i =1;
int j =2;
int k = 0;
while (k<4000000)
{
k = i +j;
i = k+j;
j=i +k;
}
cout << i <<endl;
cout << j << endl;
cout << k << endl;
return 0;
}
Am I even doing this correctly? Why am I getting three different nu
You want to find the sum of even terms in Fibonacci sequence, you can use a function that uses recursion, but that will take more time than your code since recursion will compute the Fibonacci for each element and won't store the Fibonacci of the previous numbers.
But if you want to use your code, this will be faster for the compilation to your process, but I thing your code must be like this.
int even=2;
while (k<4000000 && i<4000000 && j<4000000)
{
k = i+j; //3 13 55 i,j and k computes Fibonacci
i = k+j; //5 21 89 of sequence of numbers so
j = i+k; //8 34 144 they must differ :)
if(k%2==0)even+=k;
if(i%2==0)even+=i;
if(j%2==0)even+=j;
}
if(k>=4000000 && k%2==0)even-=k;
if(j>=4000000 && j%2==0)even-=j;
if(i>=4000000 && i%2==0)even-=i;
cout<<"even sum equals"<<even;
}
You can this code to find desired output
int evenFibSum(int limit)
{
if (limit < 2)
return 0;
// Initialize first two even prime numbers
// and their sum
long long int ef1 = 0, ef2 = 2;
long long int sum = ef1 + ef2;
// calculating sum of even Fibonacci value
while (ef2 <= limit)
{
// get next even value of Fibonacci sequence
long long int ef3 = 4*ef2 + ef1;
// If we go beyond limit, we break loop
if (ef3 > limit)
break;
// Move to next even number and update sum
ef1 = ef2;
ef2 = ef3;
sum += ef2;
}
return sum;
}

Can't quite get Project Euler problem #2 figured out [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm trying to learn the basics of C++ by going through some Project Euler problems. I've made it to...#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, ...
Find the sum of all the even-valued
terms in the sequence which do not
exceed four million.
My logic:
0, 1, 1, 2, 3, 5
x y z
x y z
x y z
x y z
The above is looping through this:
x + y = z
x = y
y = z
My code:
#include <iostream.h>
using namespace std;
int main()
{
int x = 0;
int y = 1;
int z;
int sum;
for(y = 1; y <= 4000000; y++) {
z = x + y;
x = y;
y = z;
if(y % 2 == 0) {
sum += y;
}
}
cout << sum;
cin.get();
}
That outputs 4613788
The correct answer, though, is 4613732.
You're using y as both the loop variable, and the second term in the sequence.
What you mean to do is:
int x = 0;
int y = 1;
int z;
int sum = 0;
do {
z = x + y;
x = y;
y = z;
if (y % 2 == 0) sum += y;
} while (y <= 4000000);
Noting that you should probably initialize sum as well.
For a speed improvement, note that the sequence is Even-Odd-Odd (repeats), Even-Odd-Odd.
You don't need to test each number to know if it is even or odd. Just add every third number.
You're not initialising sum to zero.
The for loop code block should be something like
while(y <= 4000000) {
z = x + y;
x = y;
y = z;
if(y % 2 == 0) {
sum += y;
}
}
Basically, you should not increment y.
Here is how we can do in minimum number of loops. If we write Fibonacci series in terms of first two numbers, it is:
a, b, (a+b), (a+2b), (2a+3b), (3a+5b), (5a+8b), (8a+13b), (13a+21b), (21a+34b), (34a+55b)....
In above series a is 1 and b is 2, highlighted numbers are even numbers. In Fibonacci series every third number is even number, sequence is EVEN-ODD-ODD-EVEN-. So if we write even number is this series, it is:
b, (2a+3b), (8a+13b), (34a+55b), (144a+233b)...
If we observe pattern in this series, coefficient_of_next_a is 4*(coefficient_of_current_a)+(coefficient_of_previous_a).
And coefficient_of_next_b is (coefficient_of_current_a)+(coefficient_of_current_b)+(coefficient_of_next_a).
Python Code:
# Start sum with first event number
sum = 2
# Values of first two Fibonacci numbers
a = 1
b = 2
# Previous coefficient of a
prev_coef_a = 0
# Current coefficient of a and b
coef_a = 2
coef_b = 3
while ((coef_a*a)+(coef_b*b)) <= 4000000:
print(((coef_a*a)+(coef_b*b)))
sum += ((coef_a*a)+(coef_b*b))
# Coefficient of a for next number
next_coef_a = (coef_a*4)+prev_coef_a
prev_coef_a = coef_a
# Coefficient of b for next number
coef_b = coef_a+coef_b+next_coef_a
coef_a = next_coef_a
print('Sum: {}'.format(sum))
Output is:
8
34
144
610
2584
10946
46368
196418
832040
3524578
Sum: 4613732
Here is a way to solve this problem in O(log(N))-time vs. the slower O(N) implementation (O(log(N)) comes from the need to use the pow() function).
First, you need to be able to compute the N-th Fibonacci number in O(log(N)) time:
double Fib(double N)
{
double Fn = (pow(PHI, N) - pow(PSI, N)) / sqrt(5);
return floor(Fn);
}
where PHI = 1.6180339... and PSI = -0.61803398... (check out wiki for more info)
Second, you will need to calculate the closest index to your target limit (in problem 2's case this would be 4,000,000):
double nFib(double F)
{
double nFib = log((double)F * sqrt(5) + 0.5) / log(PHI);
return floor(nFib);
}
Third, you will use the B&Q identity #25 (more info here) for calculating the sum of the even Fibonacci numbers:
double bqIdentity25(double N)
{
return (Fib(3*floor(N) + 2) - 1) / 2;
}
Finally, compute the sum:
double limit = 4000000;
double nearestIndex = nFib(limit);
double sum = bqIdentity25(nearestIndex / 3);
we only need every third element to compute the sum of the even Fibonacci numbers.
Hope this helps!
Will
//fibonacci sequence
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<unsigned long int> list;
list.clear();
list.push_back(1);
list.push_back(2);
cout<<"1\n2\n";
unsigned long int last;
unsigned long int prev;
do{
last=list.at(list.size()-1);
prev=list.at(list.size()-2);
list.push_back(last+prev);
cout << list.at(list.size()-1)<<'\n';
}while(last<4000000);
unsigned long int sum=0;
for(int a=0;a<list.size();a++)
{
if(list.at(a)%2==0)
{
sum+=list.at(a);
}
}
cout <<'\n'<<sum<<'\n';
return 0;
}
perl -e '$a,$b=(0,1);while($a<4*10**6){$a%2==0and$sum+=$a;$a+=$b;$c=$a;$a=$b;$b=$c;}print"$sum\n"'
I recently began studying the arcane art of Perl...(LOVE IT!)
but I will explain it... we need three variables that we will move our 2 values that we need in order to find the next step in the sequence(which will be assigned to the 3rd var like this $c=$a;$a=$b;$b=$c;). $a and $b are declared upfront because we know the fibo starts with them($a,$b=(0,1)). From there we get a a while loop rolling as long as our variable that we use in our boologic is less than 4mil(while($a<4*10**6)). Every iteration we check for even numbers($a%2==0) with modulus and plus-equals these to our $sum variable($sum+=$a). After shuffling the variables(as mentioned earlier) it's just 'print and done'.
I know you wanted to do this in C/C++ (perl is written in C) but I was just messing around with the euler problems in Perl and thought this might provide insight.
if it doesn't help at all(aside from not being the right language) please tell me how to improve my answer so I can provide better answers in the future. Most importantly, have a nice day!
Golf anyone?
It shows each Fibonacci Sequence Number and selects even ones,
at the end gives sum of the even ones.
#include <stdio.h>
#include <math.h>
#include <time.h>
//project euler
//problem# 2
int main()
{
long int a = 0;
long int b = 1;
long int sum = 0;
long int f = 0;
long int t = 1;
long int d = 1;
while (f <= 4000000){
f = a + b;
printf(" %2d. number is %7d",d,f);
d++;
a = b;
b = f;
if (f % 2 == 0){
sum += f;
printf("\t\t%2d. target is %7d",t,f);
t++;
}
printf("\n\n");
printf("--------------------------------------------------------------------------------");
}
printf("\n\n\t\t\t\t\tSum of targets is %d\n\n\n", sum);
printf("--------------------------------------------------------------------------------\n");
printf("Press any key to continue...\n");
getchar();
}
Trying to add little help to the problem.Following program shows all even fibonacci series numbers for a given length of series which is input by user.
#include<iostream.h>
#include<conio.h>
class fibonacci
{
int input;
public:
void series();
};
void fibonacci::series()
{
cout<<"enter the value";
cin>>input;
int initial=0;
int initial1=1;
for(int loop=0;loop<input;loop++)
{
int initial2;
initial2=initial1+initial;
if(initial2%2==0)
{cout<<initial2<<"\t";}
initial=initial1;
initial1=initial2;
}
}
void main()
{
fibonacci a;
a.series();
getch();
}
Here is how to do it in Swift:
/** Calculate the next even fibonacci number within a limit.
Methodology:
1) Fibonacci numbers are either odd (o) or even (e) as follows:
o, e, o, o, e, o, o, e, o, o, e, ... because of the arithmetic
rule:
Odd + Odd = Even
Even + Even = Even
Odd + Even = Odd
2) By do two rounds of fibonacci, we can get from one "e" to the
next "e". We don't need to bother checking its even.
3) To avoid re-computing past results, we ask for the past
running total to be supplied, and the past pair of fibonacci
numbers before doing our two rounds of fibonacci
4) We assume the passed in pair of fibonacci numbers don't exceed
are supplied limit, and on the next even fibonacci we can just test
for exceeding the limit there only.
5) Fibonacci numbers grow very fast (nearly doubling each time). Since
the next even is found after two iterations, it means we have exponential
growth for the next fibonacci number. For limit L, we'll find the sum
after O(log(L)) time.
#param runningTotal Total of even fibonacci numbers seen so far
#param upperLimit Limit number not to exceed the next even fibonacci
#param n0 First of an adjacent pair of fibonacci numbers with
n0 < upperLimit
#param n1 Next fibonacci number after n1 with n1 < upperLimit
#returns (updatedTotal,n3,n4) where updatedTotal is the supplied runningTotal
plus the next even fibonacci number not exceeding the supplied
upperLimit, n3 and n4 are the next pair of fibonacci numbers to be
supplied for the next call to this method
*/
func sumNextEvenFibonacci(runningTotal:Int, upperLimit:Int, n0:Int, n1:Int) -> (Int, Int, Int)
{
let n2 = n0 + n1
let n3 = n2 + n1
let n4 = n3 + n2
if (n4 < upperLimit)
{
return (runningTotal + n4, n3, n4)
}
else
{
return (runningTotal, n3, n4)
}
}
func eulerProblem_02()
{
println("Problem 2\n\nEach 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:\n 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... \n\nBy considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.\n")
var n0 = 1, n1 = 2, n2 = 0, runningTotal = 2
do
{
(runningTotal, n0, n1) = sumNextEvenFibonacci(runningTotal, 4_000_000, n0, n1)
} while (n1 < 4_000_000)
println("The answer is \(runningTotal).\n")
}
eulerProblem_02()
The program outputs:
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.
The answer is 4613732.
A solution using Kotlin, I'm using this problems to practice my math and learn this new language for me:
import java.math.BigInteger
/**
*
* https://projecteuler.net/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.
*
*/
class Problem2 {
var maxValue: Int = 4000000
// Looking for this fibonacci value
var fibonacci = 32
var fibonacciValues = hashMapOf<Int, BigInteger>(0 to BigInteger.ONE, 1 to BigInteger.ONE);
fun solution(): BigInteger {
var solution: BigInteger = BigInteger.ZERO
calculateFibonacci(fibonacci)
fibonacciValues.filter {
it.value < BigInteger.valueOf(maxValue.toLong()) &&
it.value.mod(BigInteger.ONE.add(BigInteger.ONE)).equals(BigInteger.ZERO)
}.forEach {
//println("Key: ${it.key} and ${it.value} and mv $maxValue")
solution = solution.add(it.value)
}
return solution
}
private fun calculateFibonacci(n: Int): BigInteger? {
if ( fibonacciValues.contains(n)) {
return fibonacciValues.get(n)
} else {
val f = calculateFibonacci(n - 2)!!.add(calculateFibonacci(n - 1))
fibonacciValues.put(n, f)
return f
}
}
}
It's a little verbose because, I'm adding testability, if you want to see the Unit Test, here it is:
https://github.com/moxi/project-euler-solutions/blob/master/code/src/test/kotlin/org/rcgonzalezf/onetoten/Problem2Test.kt
Every 3rd number is even, so sum of even numbers is (sum of n fib numbers)/2.
But, some of n fib. numbers = (n+2)'s term - 2nd term(1).
You can get (n+2)th term from benet's formula
In javascript you can solve it like this:
function add(a, b) {
// body...
return a + b;
}
function fabonacci(limit) {
var i = 2; //parseInt(limit);
var fabonacci = [0, 1];
var evenFab = [];
var valToPush = 0;
var result = [];
while (valToPush < 4000000) {
valToPush = fabonacci[fabonacci.length - 2] + fabonacci[fabonacci.length - 1]
i++;
if ((valToPush % 2) == 0) {
evenFab.push(valToPush);
}
if (valToPush > 4000000 || i > limit) {
break;
}
fabonacci.push(valToPush);
}
result['sequence'] = fabonacci;
result['sumOfEven'] = evenFab;
return result;
}
var result = fabonacci(10);
console.log("Fabonacci sequence:" + result['sequence']);
console.log("Sum of Even Number:" + (result['sumOfEven']).reduce(add, 0));`
a = 0
b = 1
c =0
sum = 0
d = 0
for s in range(4000000):
while(d<4000000):
d = a+b
if d%2 == 0:
sum += d
print(d)
a = b
b = d
print
print
print("the sum is:"+str(sum))
You have to use long data type instead of int .
My Solution :
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long sum = 0;
long f = 1, s = 2;
for(f, s; f<4000000 || s < 4000000; )
{
//cout << f << " " << s << endl;
if( f%2 == 0 )
sum += f;
if( s%2 == 0)
sum+= s;
f += s;
s+=f;
}
cout << sum <<endl;
return 0;
}

Triangle numbers problem....show within 4 seconds

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.
Given an integer n, display the first
triangle number having at least n
divisors.
Sample Input: 5
Output 28
Input Constraints: 1<=n<=320
I was obviously able to do this question, but I used a naive algorithm:
Get n.
Find triangle numbers and check their number of factors using the mod operator.
But the challenge was to show the output within 4 seconds of input. On high inputs like 190 and above it took almost 15-16 seconds. Then I tried to put the triangle numbers and their number of factors in a 2d array first and then get the input from the user and search the array. But somehow I couldn't do it: I got a lot of processor faults. Please try doing it with this method and paste the code. Or if there are any better ways, please tell me.
Here's a hint:
The number of divisors according to the Divisor function is the product of the power of each prime factor plus 1. For example, let's consider the exponential prime representation of 28:
28 = 22 * 30 * 50 * 71 * 110...
The product of each exponent plus one is: (2+1)*(0+1)*(0+1)*(1+1)*(0+1)... = 6, and sure enough, 28 has 6 divisors.
Now, consider that the nth triangular number can be computed in closed form as n(n+1)/2. We can multiply numbers written in the exponential prime form simply by adding up the exponents at each position. Dividing by two just means decrementing the exponent on the two's place.
Do you see where I'm going with this?
Well, you don't go into a lot of detail about what you did, but I can give you an optimization that can be used, if you didn't think of it...
If you're using the straightforward method of trying to find factors of a number n, by using the mod operator, you don't need to check all the numbers < n. That obviously would take n comparisons...you can just go up to floor(sqrt(n)). For each factor you find, just divide n by that number, and you'll get the conjugate value, and not need to find it manually.
For example: say n is 15.
We loop, and try 1 first. Yep, the mod checks out, so it's a factor. We divide n by the factor to get the conjugate value, so we do (15 / 1) = 15...so 15 is a factor.
We try 2 next. Nope. Then 3. Yep, which also gives us (15 / 3) = 5.
And we're done, because 4 is > floor(sqrt(n)). Quick!
If you didn't think of it, that might be something you could leverage to improve your times...overall you go from O(n) to O(sqrt (n)) which is pretty good (though for numbers this small, constants may still weigh heavily.)
I was in a programming competition way back in school where there was some similar question with a run time limit. the team that "solved" it did as follows:
1) solve it with a brute force slow method.
2) write a program to just print out the answer (you found using the slow method), which will run sub second.
I thought this was bogus, but they won.
see Triangular numbers: a(n) = C(n+1,2) = n(n+1)/2 = 0+1+2+...+n. (Formerly M2535 N1002)
then pick the language you want implement it in, see this:
"... Python
import math
def diminishing_returns(val, scale):
if val < 0:
return -diminishing_returns(-val, scale)
mult = val / float(scale)
trinum = (math.sqrt(8.0 * mult + 1.0) - 1.0) / 2.0
return trinum * scale
..."
First, create table with two columns: Triangle_Number Count_of_Factors.
Second, derive from this a table with the same columns, but consisting only of the 320 rows of the lowest triangle number with a distinct number of factors.
Perform your speedy lookup to the second table.
If you solved the problem, you should be able to access the thread on Project Euler in which people post their (some very efficient) solutions.
If you're going to copy and paste a problem, please cite the source (unless it was your teacher who stole it); and I second Wouter van Niferick's comment.
Well, at least you got a good professor. Performance is important.
Since you have a program that can do the job, you can precalculate all of the answers for 1 .. 320.
Store them in an array, then simply subscript into the array to get the answer. That will be very fast.
Compile with care, winner of worst code of the year :D
#include <iostream>
bool isPrime( unsigned long long number ){
if( number != 2 && number % 2 == 0 )
return false;
for( int i = 3;
i < static_cast<unsigned long long>
( sqrt(static_cast<double>(number)) + 1 )
; i += 2 ){
if( number % i == 0 )
return false;
}
return true;
}
unsigned int p;
unsigned long long primes[1024];
void initPrimes(){
primes[0] = 2;
primes[1] = 3;
unsigned long long number = 5;
for( unsigned int i = 2; i < 1024; i++ ){
while( !isPrime(number) )
number += 2;
primes[i] = number;
number += 2;
}
return;
}
unsigned long long nextPrime(){
unsigned int ret = p;
p++;
return primes[ret];
}
unsigned long long numOfDivs( unsigned long long number ){
p = 0;
std::vector<unsigned long long> v;
unsigned long long prime = nextPrime(), divs = 1, i = 0;
while( number >= prime ){
i = 0;
while( number % prime == 0 ){
number /= prime;
i++;
}
if( i )
v.push_back( i );
prime = nextPrime();
}
for( unsigned n = 0; n < v.size(); n++ )
divs *= (v[n] + 1);
return divs;
}
unsigned long long nextTriNumber(){
static unsigned long long triNumber = 1, next = 2;
unsigned long long retTri = triNumber;
triNumber += next;
next++;
return retTri;
}
int main()
{
initPrimes();
unsigned long long n = nextTriNumber();
unsigned long long divs = 500;
while( numOfDivs(n) <= divs )
n = nextTriNumber();
std::cout << n;
std::cin.get();
}
def first_triangle_number_with_over_N_divisors(N):
n = 4
primes = [2, 3]
fact = [None, None, {2:1}, {3:1}]
def num_divisors (x):
num = 1
for mul in fact[x].values():
num *= (mul+1)
return num
while True:
factn = {}
for p in primes:
if p > n//2: break
r = n // p
if r * p == n:
factn = fact[r].copy()
factn[p] = factn.get(p,0) + 1
if len(factn)==0:
primes.append(n)
factn[n] = 1
fact.append(factn)
(x, y) = (n-1, n//2) if n % 2 == 0 else (n, (n-1)//2)
numdiv = num_divisors(x) * num_divisors(y)
if numdiv >= N:
print('Triangle number %d: %d divisors'
%(x*y, numdiv))
break
n += 1
>>> first_triangle_number_with_over_N_divisors(500)
Triangle number 76576500: 576 divisors
Dude here is ur code, go have a look. It calculates the first number that has divisors greater than 500.
void main() {
long long divisors = 0;
long long nat_num = 0;
long long tri_num = 0;
int tri_sqrt = 0;
while (1) {
divisors = 0;
nat_num++;
tri_num = nat_num + tri_num;
tri_sqrt = floor(sqrt((double)tri_num));
long long i = 0;
for ( i=tri_sqrt; i>=1; i--) {
long long remainder = tri_num % i;
if ( remainder == 0 && tri_num == 1 ) {
divisors++;
}
else if (remainder == 0 && tri_num != 1) {
divisors++;
divisors++;
}
}
if (divisors >100) {
cout <<"No. of divisors: "<<divisors<<endl<<tri_num<<endl;
}
if (divisors > 500)
break;
}
cout<<"Final Result: "<<tri_num<<endl;
system("pause");
}
Boojum's answer motivated me to write this little program. It seems to work well, although it does use a brute force method of computing primes. It's neat how all the natural numbers can be broken down into prime number components.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <vector>
//////////////////////////////////////////////////////////////////////////////
typedef std::vector<size_t> uint_vector;
//////////////////////////////////////////////////////////////////////////////
// add a prime number to primes[]
void
primeAdd(uint_vector& primes)
{
size_t n;
if (primes.empty())
{
primes.push_back(2);
return;
}
for (n = *(--primes.end()) + 1; ; ++n)
{
// n is even -> not prime
if ((n & 1) == 0) continue;
// look for a divisor in [2,n)
for (size_t i = 2; i < n; ++i)
{
if ((n % i) == 0) continue;
}
// found a prime
break;
}
primes.push_back(n);
}
//////////////////////////////////////////////////////////////////////////////
void
primeFactorize(size_t n, uint_vector& primes, uint_vector& f)
{
f.clear();
for (size_t i = 0; n > 1; ++i)
{
while (primes.size() <= i) primeAdd(primes);
while (f.size() <= i) f.push_back(0);
while ((n % primes[i]) == 0)
{
++f[i];
n /= primes[i];
}
}
}
//////////////////////////////////////////////////////////////////////////////
int
main(int argc, char** argv)
{
// allow specifying number of TN's to be evaluated
size_t lim = 1000;
if (argc > 1)
{
lim = atoi(argv[1]);
}
if (lim == 0) lim = 1000;
// prime numbers
uint_vector primes;
// factors of (n), (n + 1)
uint_vector* f = new uint_vector();
uint_vector* f1 = new uint_vector();
// sum vector
uint_vector sum;
// prime factorize (n)
size_t n = 1;
primeFactorize(n, primes, *f);
// iterate over triangle-numbers
for (; n <= lim; ++n)
{
// prime factorize (n + 1)
primeFactorize(n + 1, primes, *f1);
while (f->size() < f1->size()) f->push_back(0);
while (f1->size() < f->size()) f1->push_back(0);
size_t numTerms = f->size();
// compute prime factors for (n * (n + 1) / 2)
sum.clear();
size_t i;
for (i = 0; i < numTerms; ++i)
{
sum.push_back((*f)[i] + (*f1)[i]);
}
--sum[0];
size_t numFactors = 1, tn = 1;
for (i = 0; i < numTerms; ++i)
{
size_t exp = sum[i];
numFactors *= (exp + 1);
while (exp-- != 0) tn *= primes[i];
}
std::cout
<< n << ". Triangle number "
<< tn << " has " << numFactors << " factors."
<< std::endl;
// prepare for next iteration
f->clear();
uint_vector* tmp = f;
f = f1;
f1 = tmp;
}
delete f;
delete f1;
return 0;
}