Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Find original numbers from gcd() every pair in Python
Given an array containing GCD (Greatest Common Divisor) values of every possible pair from an original array, we need to reconstruct the original numbers. This is a reverse engineering problem where we work backwards from the GCD results.
Problem Understanding
If we have an original array like [13, 6], the GCD array would contain ?
- gcd(13, 13) = 13
- gcd(13, 6) = 1
- gcd(6, 13) = 1
- gcd(6, 6) = 6
So the GCD array becomes [13, 1, 1, 6]. Our task is to reverse this process.
Algorithm Steps
The key insight is that the largest element in the GCD array must be from the original array (since gcd(x,x) = x). We use this to reconstruct step by step ?
- Sort the GCD array in descending order
- Track occurrence count of each element
- Pick the largest unused element as part of original array
- Remove its GCD contributions with previously selected elements
- Repeat until we have reconstructed the original array
Implementation
from math import sqrt, gcd
def get_original_array(gcd_array):
n = len(gcd_array)
gcd_array.sort(reverse=True)
# Count occurrences of each GCD value
occurrence = [0 for i in range(gcd_array[0] + 1)]
for i in range(n):
occurrence[gcd_array[i]] += 1
# Original array size is sqrt(n)
original_size = int(sqrt(n))
result = [0 for i in range(len(gcd_array))]
count = 0
for i in range(n):
if occurrence[gcd_array[i]] > 0:
# Add this element to result
result[count] = gcd_array[i]
occurrence[result[count]] -= 1
count += 1
# Remove GCD contributions with previous elements
for j in range(count):
if i != j:
g = gcd(gcd_array[i], result[j])
occurrence[g] -= 2
return result[:original_size]
# Test the function
A = [6, 1, 1, 13]
original = get_original_array(A)
print("GCD Array:", A)
print("Original Array:", original)
GCD Array: [6, 1, 1, 13] Original Array: [13, 6]
How It Works
Let's trace through the example with GCD array [6, 1, 1, 13] ?
-
Sort descending:
[13, 6, 1, 1] - Count occurrences: 13?1, 6?1, 1?2
- Pick 13: Add to result, decrease count of 13
- Pick 6: Add to result, decrease count of 6 and gcd(13,6)=1 by 2
-
Result:
[13, 6]
Verification Example
from math import gcd
def verify_solution(original, gcd_array):
"""Verify if original array produces the given GCD array"""
calculated_gcd = []
for i in range(len(original)):
for j in range(len(original)):
calculated_gcd.append(gcd(original[i], original[j]))
calculated_gcd.sort()
gcd_array.sort()
return calculated_gcd == gcd_array
# Test verification
original = [13, 6]
gcd_array = [6, 1, 1, 13]
print("Original array:", original)
print("Is solution correct?", verify_solution(original.copy(), gcd_array.copy()))
# Show all GCD pairs
for i in range(len(original)):
for j in range(len(original)):
print(f"gcd({original[i]}, {original[j]}) = {gcd(original[i], original[j])}")
Original array: [13, 6] Is solution correct? True gcd(13, 13) = 13 gcd(13, 6) = 1 gcd(6, 13) = 1 gcd(6, 6) = 6
Time Complexity
The algorithm runs in O(n² log(max_value)) time where n is the length of the GCD array. The sorting takes O(n log n) and the nested loop with GCD calculations takes O(n² log(max_value)).
Conclusion
This algorithm successfully reconstructs the original array by leveraging the property that the largest GCD values must come from self-pairs. By systematically removing GCD contributions, we can reverse-engineer the original numbers from their pairwise GCD results.
