Project Euler Problem 9: Solution in C++

Special Pythagorean triplet

A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,

a2 + b2 = c2

For example, 32 + 42 = 9 + 16 = 25 = 52.

There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.

/*
    Author      :   Sreejith Sreekantan
    Description :   
                    Special Pythagorean triplet
                    Problem 9

                    A Pythagorean triplet is a set of three natural numbers, 
                    a < b < c, for which, a2 + b2 = c2

                    For example, 32 + 42 = 9 + 16 = 25 = 52.

                    There exists exactly one Pythagorean triplet for which 
                    a + b + c = 1000.
                    Find the product abc.

    Eg: for Pythagorean triplets:
    (3, 4, 5 )  (5, 12, 13)     (8, 15, 17)     (7, 24, 25)
    (20, 21, 29)    (12, 35, 37)    ( 9, 40, 41)    (28, 45, 53)
    (11, 60, 61)    (16, 63, 65)    (33, 56, 65)    (48, 55, 73)
    (13, 84, 85)    (36, 77, 85)    (39, 80, 89)    (65, 72, 97)
    (20, 99, 101)   (60, 91, 109)   (15, 112, 113)  (44, 117, 125)
    (88, 105, 137)  (17, 144, 145)  (24, 143, 145)  (51, 140, 149)
    (85, 132, 157)  (119, 120, 169)     (52, 165, 173)  (19, 180, 181)
    (57, 176, 185)  (104, 153, 185)     (95, 168, 193)  (28, 195, 197)
    (84, 187, 205)  (133, 156, 205)     (21, 220, 221)  (140, 171, 221)
    (60, 221, 229)  (105, 208, 233)     (120, 209, 241) (32, 255, 257)
    (23, 264, 265)  (96, 247, 265)  (69, 260, 269)  (115, 252, 277)
    (160, 231, 281)     (161, 240, 289)     (68, 285, 293)

*/
#include 
#include 


using namespace std;

void pythagoreanTriplet(unsigned long sum)
{
    unsigned long m, n, s=sum;
    s /= 2;
    unsigned long sqrt_s = sqrt(s);

    for (int m = 1; m <= sqrt_s ; ++m)
    {
        if (s%m==0)
        {
            n = (s/m)-m;
            if (m>n)
            {
                cout << sum << " : " << pow(m,2)-pow(n,2) << " "  
                << 2*m*n << " "  << pow(m,2)+pow(n,2) << endl;
            }
        }
    }

}


int main(int argc, char const *argv[])
{
    unsigned long sums[] = {12, 30, 40, 56, 70, 84, 90, 126, 132, 
                            144, 176, 182, 1000};
    for (int i = 0; i < sizeof(sums)/sizeof(unsigned long); ++i)
    {
            pythagoreanTriplet(sums[i]);
    }

    cout << " the end..." << endl;
    return 0;
}


Project Euler Problem 8: Solution in C++

/*

Largest product in a series

Find the greatest product of five consecutive digits in the 1000-digit number.

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
*/
#include<iostream>

using namespace std;

int main()
{
string s = “7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450”;
//cin >> s;
int max_prod = 1;
int ans_start = 0; // answer ie. 5 consecutive numbers starts at ans_start
for( int i = 0; i < 5; i++ )
{
max_prod *= static_cast(s[i]-‘0’);
}

int prod = max_prod;
for( int i = 5; i < s.size(); i++ )
{

if( static_cast(s[i-5]-‘0’) != 0 )
{
prod /= static_cast(s[i-5]-‘0’);
}
if( static_cast(s[i]-‘0’) == 0 )
{
clog << “skipped ” << “i = ” << i << ” s[i] = ” << s[i] << endl;
continue;
}
clog << “i = ” << i << ” s[i] = ” << s[i];
prod *= static_cast(s[i]-‘0’);
clog << ” prod = ” << prod << ” /= ” << static_cast(s[i-5]-‘0’) << ” *= ” << static_cast(s[i]-‘0’) << ” max_prod = ” << max_prod;
if( max_prod < prod )
{

ans_start = i-4;
max_prod = prod;
}
cout << ” ans_start = ” << ans_start << endl;
}

for( int i = ans_start; i < ans_start+5; i++ )
{
cout << s[i] << ” “;
}
cout << endl << max_prod << endl;
}

//    7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883
//    99879
//    7908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450

// ANSWER IS 40824

Project Euler Problem 7: Solution in C++

/*

10001st prime

*/

#include <iostream>
#include <cmath>

using namespace std;

bool isPrime( long num )
{
switch( num )
{
case 1:
case 4:
case 6:
case 8:
case 9:
return false;
break;
case 2:
case 3:
case 5:
case 7:
return true;
break;
}
if( num % 2 == 0 || num % 3 == 0 )
return false;
long sq_root_of_num = floor( sqrt(num) );
long i = 5;
while( i <= sq_root_of_num )
{
if( num % i == 0 || num % (i+2) == 0 )
{
return false;
}
i += 6;
}

// num is prime
return true;
}

int main()
{
long num = 3;
int index = 1;

while( index < 10001 )
{
if( isPrime( num ) )
{
index++;
}
num += 2;
}
num -= 2;
cout << num << endl;
}

// ANSWER is 404743

Euler Problem: Solution of Problem-6 in C++

Q)The sum of the squares of the first ten natural numbers is,

#include  

#define N 100

using namespace std;

long raiseTo ( const long num, const long n ) {
    int ans = num;
    for ( int i = 1; i < n; i++ ) {
        ans *= num;
    }
    return ans;
}

int main ( int argc, char * argv[] ) {
    long result =     (             ( raiseTo ( N, 4 ) / 4 ) 
                            +     ( raiseTo ( N, 3 ) / 6 ) 
                            -     ( raiseTo ( N, 2 ) / 4 ) 
                            -    ( N / 6 ) 
                    ); 
    cout << result << endl;
}

// 25164150

Euler Problem: Solution of Problem-5 in C++

#include 

#define X 20

using namespace std;

long hcf ( const long & small_num, const long & big_num ) {
    if ( small_num > big_num ) {
        return hcf ( big_num, small_num );
    }
    else {
        if ( big_num % small_num == 0 ) {
            return small_num;
        }
        else {
            return hcf ( big_num % small_num, small_num );
        }
    }
}

int main ( int argc, char *argv[] ) {
    long result = 1;
    long temp_hcf;
    for ( int i = 1; i <= X; i++ ) {
        temp_hcf = hcf ( result, i );
        result /= temp_hcf;
        result *= i;
    }
    cout << "Result = " << result << endl;
    return 0;
}

// Result = 232792560

Euler Problem: Solution of Problem-4 in C++

Q) A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 * 99. Find the largest palindrome made from the product of two 3-digit numbers.

Lets take the case: largest palindrome made from the product of two single-digit numbers.
what will be the smallest product of two single-digit numbers?
of-course the product of two smallest-single-digit numbers ie. 0 and 0 ie. 0-
and the largest product?
product of two largest-single-digit numbers ie. 9 and 9 ie. 81

Now we are interested in only palindrome numbers, that too between the above found numbers 
( 0 and 81 )List of palindrome numbers between 0 and 81: 1, 11, 22, 33, 44, 55, 66, 77
Note: 88 and 99 won't get into the list.
since we are looking for largest palindrome number which will be the product of two single-digit numbers,
let's go through the list from highest to lowest and with each number in the list, we will check if it is 
a product of two one digit number. 
We will stop traversing through the list of numbers when we find such a number.

Now let's do a little optimization to our logic. Why do we need to generate a list of all palindrome numbers 
below 81?
So first we will find the immediate palindrome number below 81, will check if it suffice our need, 
if not go for next.
Better.. , isn't it?

The same logic can be scaled up to find largest palindrome made from the product of two n-digit numbers.

We make use of a function in our code to divide the task.
"palindromeNumJustBelow ( input )":
returns the palindrome number just below the argument.
Rather than a brute-force search I use a few heuristics here:
	A palindrome number is a smaller number combined with the same number reversed.
	Eg:
		1221 = 12 combined with reverse of 12 ie 21
		765567 = 765 combined with reverse(765)
	In case of odd number of digits, it will be similar to above case but a digit in between.
	Eg:
		12821 = '12' + a digit(here '8') + reverse(12)
		12321 = '12' + '3' + '21'
	So a palindrome less than a number can be found by splitting the number into two sub-parts:
	In case of even number of digits:
		two numbers of half the number of digits ie 1221 into 12 and 21, 765567 into 765 and 567
	In case of odd number of digits:
		the small number and middle digit forms first number and reversed number forms the second 
		number ie 12821 into 128 and 21, 12321 into 123 and 21.
	Now the first number is decremented by 1. Eg: 12 of 1221 becomes 11, 765 of 765567 becomes 764
		128 of 12821 becomes 127, etc
	Now we just need to take the reverse of particular digits of this new number and append to the new 
        number to get the required palindrome number.
		ie. 	in case of even number of digits, just reverse the new number.
			in case of odd number of digits, reverse all digits except the last.

	Lets try our logic with a few numbers to ensure its correctness:
	1) Find the palindrome number just below 139890?
		This number has even number of digits ( 6 digits)
		It is split into two sub-parts: 139 and 890
		Now the first number is decremented by 1 and becomes 138.
		Now the reverse of new number is appended with the new number  to form the final answer.
			ie '138' + '831' = 138831 (Note: + doesn't mean mathematical addition)
		You may have a doubt now, why the first number is reduced and not the second number.
			If we reduce the second number and prepend with the reverse of new number, we wont get
			the expected result. In this case (831 - 1) = 830, '038' + '830' = 038830. Is this what
                        we wanted? 
			A BIG NO... !

	Now with a number of odd number of digits:
	2) 1637001
		yes, you are right, 7 digits
		right.., split into 1637 and 001
		Note: 001 wont be considered as 1
		1637 is decremented by 1 and becomes 1636
		Now, since odd number of digits, only 1, first 6 and 3 is reversed and appended.
		So final answer becomes: 1636361

	Lets go for one more
	3)	13300029212
		11 digits.
		133000 and 29212
		133000 - 1 = 132999
		'132999' + '99231' = 13299999231

"palindromeNumJustBelow ( long input )" implementation:
First, I insert each digit of the argument ie input into a vector. so the vector can be seen as an array 
of digits. This is for my easiness to handle the digits of the number. Since I use the push_back() function 
of the vector, The order of the digits will be reversed. Then I set a variable numOfDigits to number of digits 
in the number. Then a new number ie 'temp_input_half' is generated with last
half of digits (Note: last half digits means first half digits of the number, don't get confused).
'temp_input_half' is decremented by 1.
The second half digits in the vector are replaced with the digits of new value of 'temp_input_half'
Now our final array of digits is ready; we just need to form the final number out of it.
I have used two lambda functions in the code. It's just a way to define a function somewhere just for one time 
use. I use those with for_each loop.

At the top of the program, num_of_digits_in_num is defined as 3, ie. it should be a multiple of two 3-digit 
numbers.

In the main function:
I find 
	smallest 3-digit number 
		( to avoid hard-coding, we use 'num_of_digits_in_num', 
		so when i say 3 assume that I used 'num_of_digits_in_num' in the code) 
	largest 3-digit number
Then the execution gets into a while loop which exits if the "palindrome_num" (palindrome number) is less than 
the product of two smallest-3-digit-number. Product of two 3-digit-number should be between product of two 
smallest 3-digit number and product of two largest 3-digit number. It's simple mathematics.

Note: first the "palindrome_num" is set to product of two largest 3-digit number before the while-loop

Inside while-loop, we find a number just below the current "palindrome_num" and we use another for-loop which 
iterates from largest 3-digit number to smallest 3-digit number and in each iteration it is checked if it's 
possible to divide the palindrome number with the iteration variable (in our code, "temp_div1") and still get 
a 3-digit number

Largest palindrome made from the product of two 3-digit numbers is 906609 = 993 * 913


Code for reference:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <vector>
#include <boost/lambda/lambda.hpp>
#include <boost/functional.hpp>
#include <boost/function.hpp>

#define num_of_digits_in_num 3

using namespace std;
using namespace boost::lambda;

long palindromeNumJustBelow ( long input ) {
    vector inputAsArray; //array of single-digit-numbers

    long temp = input;
    while ( temp ) {
        inputAsArray.push_back ( temp%static_cast(10) );
        temp = floor( temp/static_cast(10) );
    }

    int numOfDigits = inputAsArray.size();

    temp = floor ( ( inputAsArray.size()/2 ) ) ;
    long temp_input_half = 0;
    boost::function f2 = ( var(temp_input_half)*=10, var(temp_input_half)+=boost::lambda::_1);
    for_each ( inputAsArray.rbegin(), inputAsArray.rend()-temp, f2 );

    temp_input_half--;

    long temp1 = temp;
    while ( temp_input_half ) {
        inputAsArray [ temp1++ ] = ( temp_input_half%static_cast(10) );
        temp_input_half = floor( temp_input_half/static_cast(10) );
    }

    // mirror all the digits from index temp till end
    while ( temp < numOfDigits ) {
        inputAsArray [ numOfDigits - temp -1 ] = inputAsArray [ temp ] ;
        temp ++ ;
    }

    temp = 0;
    boost::function f1 = ( var(temp)*=10, var(temp)+=boost::lambda::_1);

    for_each ( inputAsArray.rbegin(), inputAsArray.rend(), f1 );

    return temp;
}
int main ( int argc, char * argv[] ) {

    long num_min, num_max;
    if ( num_of_digits_in_num==1 ) {
        num_min = 0;
    }
    else {
        num_min = pow( static_cast(10), static_cast(num_of_digits_in_num-1) );
    }

    num_max = (pow( static_cast(10), static_cast(num_of_digits_in_num) ) - 1 );

    long prod_min, prod_max;
    prod_min = num_min*num_min;
    prod_max = num_max*num_max;

    long palindrome_num = prod_max;
    long temp_div2;

    bool ans_found = false;
    while ( palindrome_num > prod_min && !ans_found) {
        palindrome_num = palindromeNumJustBelow(palindrome_num);

        for (int temp_div1 = num_max; temp_div1 >= num_min && !ans_found; temp_div1-- ) {
            temp_div2 = palindrome_num/temp_div1;
            if ( palindrome_num % temp_div1 == 0 && temp_div2 <= num_max && temp_div2 >= num_min ) {
                cout << "Largest palindrome made from the product of two " 
                << num_of_digits_in_num << "-digit numbers is " << palindrome_num
                << " = " << temp_div1 << " * " << temp_div2 << endl;
                ans_found = true;
            }

        }
    }
}

Euler Problem: Solution of Problem-3 in C++

Q) The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 ?

#include <algorithm>
#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

unsigned long largest_prime_factor_of ( unsigned long num ) {
    clog << "largest_prime_factor_of(" << num << ")" << endl;
    unsigned long largest_prime_divisor = -1;
    if ( num < 2 ) {
        return -1;
    }
    else if ( num >=2 && num<=3 ) {
        return num;
    }
    while ( num%static_cast<unsigned long>(2) == 0 ) {
        largest_prime_divisor = 2;
        cout << "/2" << endl;
        //cout << "num%static_cast(2) = " << num%static_cast(2) << " num/static_cast(2) = " << num/static_cast(2) << endl;
        num /= 2;
    }
    while ( num%3 == 0 ) {
        largest_prime_divisor = 3;
        cout << "/3" << endl;
        //cout << "num%static_cast(3) = " << num%static_cast(3) << " num/static_cast(3) = " << num/static_cast(3) << endl;
        num /= 3;
    }
    
    vector<unsigned long> prime_num_vector;
    prime_num_vector.push_back(static_cast<unsigned long>(3));
    
    clog << "largest_prime_divisor(after checking till 3) = " << largest_prime_divisor << "and num = " << num << endl; 

    unsigned long divisor = 3;
    bool divisor_is_prime;
    while ( (divisor+2) <= num ) {
        //cout << ".";
        divisor += 2;
        clog << "divisor = " << divisor << endl;
        divisor_is_prime=true;
        double sqrt_of_divisor = sqrt(divisor);
        clog << "sqrt_of_divisor = " << sqrt_of_divisor << endl;
        clog << "going inside for-loop" << endl;
        for( vector::iterator iter = prime_num_vector.begin(); 
             iter != prime_num_vector.end();
             iter++) 
        {
            clog << "\t*iter = " << *iter << endl;
            if ( *iter > sqrt_of_divisor ) {
                clog << "\t*iter > sqrt_of_divisor" << endl;
                break;
            }
            if ( divisor % *iter == 0 ) {
                clog << "\tdivisor_is_prime = false" << endl;
                divisor_is_prime = false;
                break;
            }
        }
        if ( divisor_is_prime ) {
            clog << "divisor_is_prime (" << divisor << ")" << endl;
            prime_num_vector.push_back ( divisor );
            
            while ( num % divisor == 0 ) {
                largest_prime_divisor = divisor;
                num /= divisor;
                cout << "largest_prime_divisor changed to " << largest_prime_divisor << " and num = " << num << endl;
            }
        }
    }
    clog << "returning " << largest_prime_divisor << endl;
    return largest_prime_divisor;
}

int main ( int argc, char *argv[] ) {
    unsigned long l = 600851475143 ;
    //unsigned long l = 12 ;
    cout << endl << "largest_prime_factor_of(l) = " << largest_prime_factor_of(l) << endl;
}