Pairs of Amicable Numbers

3

Given an array of integers, print the number of pairs in the array that form an amicable pair. Two numbers are amicable if the first is equal to the sum of divisors of the second, and if the second number is equal to the sum of divisors of the first.

Examples:

Input  : arr[] = {220, 284, 1184, 1210, 2 , 5}
Output : 2
Explanation : (220, 284) and (1184, 1210) 
              form amicable pair

Input  : arr[] = {2620, 2924, 5020, 5564, 6232, 6368}
Output : 3
Explanation : (2620, 2924), (5020, 5564) and (6232, 6368)
              forms amicable pair

A simple solution is to traverse each pair and check if they form an amicable pair, if they do we increment the count.

// A simple C++ program to count amicable pairs
// in an array.
#include <bits/stdc++.h>
using namespace std;

// Calculate the sum of proper divisors
int sumOfDiv(int x)
{
    // 1 is a proper divisor
    int sum = 1;
    for (int i=2; i<=sqrt(x); i++)
    {
        if (x%i == 0)
        {
            sum += i;

            // To handle perfect squares
            if (x/i != i)
                sum += x/i;
        }
    }
    return sum;
}

// Check if pair is amicable
bool isAmicable(int a,int b)
{
    return(sumOfDiv(a) == b && sumOfDiv(b) == a);
}

// This function prints pair of amicable pairs
// present in the input array
int countPairs(int arr[],int n)
{
    int count = 0;

    // Iterate through each pair, and find
    // if it an amicable pair
    for (int i=0; i<n; i++)
        for (int j=i+1; j<n; j++)
            if (isAmicable(arr[i], arr[j]))
                count++;

    return count;
}

// Driver code
int main()
{
    int arr1[] = {220, 284, 1184, 1210, 2, 5};
    int n1 = sizeof(arr1)/sizeof(arr1[0]);
    cout << countPairs(arr1, n1) << endl;

    int arr2[] = {2620, 2924, 5020, 5564, 6232, 6368};
    int n2 = sizeof(arr2)/sizeof(arr2[0]);
    cout << countPairs(arr2, n2);
    return 0;
}

Output:

2
3

An efficient solution is be to keep the numbers stored in a map and for every number we find the sum of its proper divisor and check if that’s also present in the array. If it is present, we can check if they form an amicable pair or not.

Thus, the complexity would be considerably reduced. Below is the C++ program for the same.

// Efficient C++ program to count Amicable
// pairs in an array.
#include <bits/stdc++.h>
using namespace std;

// Calculate the sum of proper divisors
int sumOfDiv(int x)
{
    // 1 is a proper divisor
    int sum = 1;
    for (int i=2; i<=sqrt(x); i++)
    {
        if (x%i == 0)
        {
            sum += i;

            // To handle perfect squares
            if (x/i != i)
                sum += x/i;
        }
    }
    return sum;
}

// Check if pair is amicable
bool isAmicable(int a, int b)
{
    return (sumOfDiv(a) == b && sumOfDiv(b) == a);
}

// This function prints count of amicable pairs
// present in the input array
int countPairs(int arr[], int n)
{
    // Map to store the numbers
    unordered_set<int> s;
    int count = 0;
    for (int i=0; i<n; i++)
        s.insert(arr[i]);

    // Iterate through each number, and find
    // the sum of proper divisors and check if
    // it's also present in the array
    for (int i=0; i<n; i++)
    {
        if (s.find(sumOfDiv(arr[i])) != s.end())
        {
            // It's sum of proper divisors
            int sum = sumOfDiv(arr[i]);
            if (isAmicable(arr[i], sum) )
                count++;
        }
    }

    // As the pairs are counted twice, thus
    // divide by 2
    return count/2;
}

// Driver code
int main()
{
    int arr1[] = {220, 284, 1184, 1210, 2 , 5};
    int n1 = sizeof(arr1)/sizeof(arr1[0]);
    cout << countPairs(arr1, n1) << endl;

    int arr2[] = {2620, 2924, 5020, 5564, 6232, 6368};
    int n2 = sizeof(arr2)/sizeof(arr2[0]);
    cout << countPairs(arr2, n2) << endl;
    return 0;
}

Output:

2
3

This article is contributed by Ashutosh Kumar If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



3 Average Difficulty : 3/5.0
Based on 4 vote(s)










Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.