Friday, April 20, 2012

Project Euler Problem 23 Solution

//Project Euler Problem 23 Solution
//Language Used:C++

#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "iostream"
#include "fstream"
#include "string"
#include "list"
#include "vector"
#include "map"

using namespace std;



int SumOfDivisors(int i)
{
int sum = 0;
for (int j=1;j<i;j++)//Just proper Divisors
{
if(i%j ==0)
{
sum += j;
}
}
return sum;
}
int main()
{

long long int NonAbundantSum = 0, totalSum=0;
vector <int> Abundant;//using push_back will actually help us create a dynamic vector and hence no need to define vector size.
vector <int> Numbers;
int abundantcounter=0, nonabundantcounter=1;

vector <int> SumNo;
string printword ="";

for(int i=1; i<=/*28123*/20161; i++)
{
    Numbers.push_back(i);
    totalSum += i;// find sum of all the numbers from 1 to 28123 and then subract all the values in SumNo

    if (i<SumOfDivisors(i))//abundant if its sum exceeds the no itself
        {
            Abundant.push_back(i);   
           
        }
}
//Sameer: I modified a piece of code here where I was actually storing the Sum of abundant numbers and then trying to do the subtraction. This was lengthy as I realized that even after running my code for 3 minutes, there was no answer. So, then I referred to one of the articles(mentioned below) and stored all the numbers from 1 to 28122 inside a vector which was then used in mapping locations of sums of abundant numbers.
//Also, according to wolfram every number after 20161 can be expressed as abundant number. So, we can cut
for (int j=0; j<Abundant.size();j++)
{
    // Compare abundant[j] to every other element AND ITSELF in the vector.
    for (int p=0;p<Abundant.size();p++)
    {
        bool found = false;
        int temp = Abundant[j]+Abundant[p]-1;//-1 is because eg j=p=25, we need to check 50. however Numbers vector begins at 1, Numbers[0]=1. So, Numbers[49]=50
        if(temp<=/*28123-1*/20161-1) //for -1 Same logic applies here
        {
           
            totalSum -= Numbers[temp];
            Numbers[temp] = 0;
   
        }
    }
}
NonAbundantSum = totalSum;//The remaining value is the non abundant sum (sum of numbers that cannot be expressed as the sum of two abundant numbers
cout<<endl<<NonAbundantSum;


return 0;
}

/*Following links were helpful:
//http://www.mathblog.dk/project-euler-23-find-positive-integers-not-sum-of-abundant-numbers/
//http://mathworld.wolfram.com/AbundantNumber.html
//http://siralansdailyramble.blogspot.com/2009/04/project-euler-23.html
*/

No comments:

Post a Comment