I have got a solution for problem 21 in python and it gives the right answer. I tried out someone else’s java code and I get the same answer for a value of 10000 and 100000 but when 1000000 is tried, the solution returned by my code differs from two other solutions returned by java code even though all three solutions returned are same for tested values of 10000 and 1000000 and 50000. Anyone got any ideas?
My Python code
def amicable_pairs(n):
"""returns sum of all amicable pairs under n. See project euler for
definition of an amicable pair"""
div_sum = [0]*n
amicable_pairs_set = [0]*n
for i in range(1, n):
for j in range(i*2, n, i):
div_sum[j] += i
#for i in range(1, n):
# div_sum[i] = sum([j + i/j for j in range(2, int(math.sqrt(i)) + 1) if i % j == 0 and i != i/j])
# div_sum[i] = div_sum[i] + 1
#print div_sum
for j in range(n):
if div_sum[j] < n and div_sum[div_sum[j]] == j and div_sum[j] != j:
amicable_pairs_set[j] = j
amicable_pairs_set[div_sum[j]] = div_sum[j]
return sum(amicable_pairs_set)
Java code 1:
public class AmicableNumbers {
public static void main(String[] args) {
long strTime = System.currentTimeMillis();
int sum_ami = 0;
for (int j = 1; j < 1000000; j++) {
int ad = sum_devisors(j);
if (((sum_devisors(ad)) == j) && (j != ad)) {
sum_ami += j;
}
}
System.out.println(sum_ami);
long endTime = System.currentTimeMillis();
System.out.println("time is " + (endTime - strTime) + " ms");
}
public static int sum_devisors(int number) {
if ((number == 1) || (number == 2)) {
return 1;
}
int sum = 0;
int k = (int) Math.sqrt(number);
for (int i = 2; i < k; i++) {
if (number % i == 0) {
sum += i;
sum += (number / i);
}
}
if (k * k == number) {
sum += k;
}
return (sum + 1);// every number divided by 1
}
}
Java code 2:
import java.util.Scanner;
public class AmicableNumbers {
/**
* @author Pavan Koppolu
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//scan the input
System.out.println("Enter a number, to find out sum of amicable numbers: ");
Scanner scan=new Scanner(System.in);
int input=scan.nextInt();
long before=System.currentTimeMillis();
// getting the result
long result=sumOfAllAmicableNumbersUptoGivenNumber(input);
long after=System.currentTimeMillis();
// prints the result on the console
System.out.println("Sum of all amicable numbers below "+input+" : "+result+" Elasped Time : "+(after-before)+" ms");
}
/*
* calculate the sum of the amicable numbers upto the given number
*/
private static long sumOfAllAmicableNumbersUptoGivenNumber(int input)
{
long sum=0,factorsSum=0,sumOfFactors=0;
for(long j=2;j<input;j++)
{
factorsSum=getFactorsSum(j);
if(j!=factorsSum)
{
sumOfFactors=getFactorsSum(factorsSum);
if(j==sumOfFactors)
sum+=j;
}
else
continue;
}
return sum;
}
/*
* find out the sum of the factors
*/
private static long getFactorsSum(long j)
{
long sum=1;
for(int k=2;k<=Math.sqrt(j);k++)
{
if(j%k==0)
sum+=k+j/k;
}
return sum;
}
}
In fact the solutions returned by all three above differ from each other for an input of 1000000
The point is that there are amicable pairs where one partner is less than 1 million and the other is larger than 1 million, namely
The Python code doesn’t count them,
but the Java code counts the smaller members of these pairs. That explains the output of the second Java code, since
The output of the first Java code is smaller because it omits the amicable pair
The reason is that
but in the code there is
thus the divisor sum is miscalculated for all numbers divisible by
floor(sqrt(n))that are not squares (Note that the second Java code miscalculates the divisor sum for all squares).