# Array Pair Sum Divisibility Problem

The computational challenge known as the Array Pair Total Divisibility Problem involves identifying pairs of elements in an array whose sum is divisible by a specified divisor. Given an array of integers and a divisor 'k,' the objective is to discover all pairs of elements (arr[i], arr[j]) for which (arr[i] + arr[j]) is evenly divisible by 'k.'

In the context of this problem, a pair (arr[i], arr[j]) is considered suitable if (arr[i] + arr[j]) % k == 0.

For instance, consider the array arr = [8, 4, 7, 6, 2] and the divisor k = 4. The task is to identify pairs of elements in the array such that their sum is divisible by 4.

Example:

• Pair (8, 4): 8 + 4 = 12, and 12 is divisible by 4.
• Pair (7, 1): 7 + 1 = 8, and 8 is divisible by 4.
• Pair (6, 2): 6 + 2 = 8, and 8 is divisible by 4.

Therefore, the valid pairs for this example are (8, 4), (7, 1), and (6, 2).

### Algorithm

Input:

• An array arr of integers.
• The size n of the array.
• A divisor 'k'.

Output:

List or count of pairs whose sum is divisible by 'k'

Steps

1. Initialize Data Structures:

• Create an array remainderHash of size k to store the count of remainders.
• Initialize the array elements to zero.

2. Iterate through the Array:

For each element arr[i] in the array:

• Calculate the remainder when dividing arr[i] by k. Let's call it the remainder.
• Calculate the complement needed for divisibility: complement = (k - remainder) % k.

3. Check Complement in Hash Table:

• Check if remainderHash[complement] is greater than zero:
• If true, print the pair (arr[i], complement) as part of the result.

4. Update Hash Table:

• Increment the count of remainderHash[remainder] to account for the current remainder.

5. Output Result:

• The result will be the list of pairs whose sum is divisible by k.

6. Cleanup:

• Free any dynamically allocated memory, if applicable.

Pseudocode

### Approach 1: Brute Force Method

The easiest technique is to examine all potential pairings in the array using the brute force method. Calculate the sum of each pair and see if it is divisible by the given division. Although this method is straightforward, it has O(n^2) time complexity, which makes it inefficient for large data sets.

Implementation

Output:

Explanation

1. The bruteForcePairSumDivisibility function takes as parameters the array arr, its size n, and the divisor k.
2. In the implementation, two nested loops iterate through all pairs of elements in the array. An outer wire (governed by i) goes from the first element to the second to the last, and an inner wire (governed by j) goes from the next element to the last element on
3. For every two elements, a sum is calculated ( pairSum = arr[i] + arr[j]).
4. The sum is then checked to see if it is divisible by the given partition (if (pairSum % k == 0)). The average of the two is printed as part of the results.
5. The main function demonstrates the usage of the bruteForcePairSumDivisibility function with the example array [8, 4, 7, 6, 2] and divisor 4.

### Approach 2: Hashing

Using a hash table may greatly enhance efficiency. Iterate through the array, calculating the complement (divisor - element) for each element. Check to see if this complement is in the hash database. If affirmative, a pair has been discovered. The temporal complexity of this approach is O(n), making it more scalable than the brute force method.

Implementation

Output:

Explanation

1. The hashingPairSumDivisibility function takes an array arr, its size n, and a divisor k as parameters.
2. Inside the function, a dynamically allocated array remainderHash is created to serve as a hash table. This array is initialized to store the count of remainders when elements are divided by k.
3. The function then iterates through the array. For each element, it calculates the remainder when divided by k.
4. It also calculates the complement needed for divisibility (complement = (k - remainder) % k).
5. It checks if the complement is present in the hash table (if (remainderHash[complement] > 0)). If yes, it prints the pair as part of the result.
6. The hash table is updated with the current remainder count.
7. Finally, the dynamically allocated memory for the hash table is freed.

### Approach 3: Counting Remainders

Counting the occurrences of remainders while dividing each element by the divisor is used in this method. We may identify couples more efficiently and determine if their total is divisible by the provided divisor by keeping track of the counts of each remainder. This approach is very effective when the divisor is tiny.

Implementation

Output:

Explanation

1. The countingRemaindersPairSumDivisibility function takes an array arr, its size n, and a divisor k as parameters.
2. It initializes an array remainderCount to store the counts of remainders and initializes each element to zero.
3. It iterates through the array, calculates the remainder for each element, and updates the counts in the remainderCount array.
4. The function then calculates the count of pairs with the sum divisible by k based on the counts of remainders.
5. The main function demonstrates the usage with the example array [8, 4, 7, 6, 2] and divisor 4.

### Approach 4: Sorting

Sort the array from highest to lowest. Then, employ a two-pointer method, one commencing at the beginning and the other at the finish. Adjust the pointers based on the current pair's total relative to the divisor. Because of the sorting phase, this approach has a temporal complexity of O(n log n).

Implementation

Output:

Explanation

1. The compare function is used for sorting in ascending order.
2. The sortingPairSumDivisibility function sorts the array using qsort and then uses two pointers (left and right) to find pairs whose sum is divisible by k.
3. The main function demonstrates the usage with the example array [8, 4, 7, 6, 2] and divisor 4.