106 lines
3.7 KiB
Python
Executable File
106 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys
|
|
from typing import List
|
|
from collections import defaultdict
|
|
|
|
"""
|
|
Given an unsorted array A[]. The task is to print all unique pairs in the unsorted array with equal sum.
|
|
Note: Print the result in the format as shown in the below examples.
|
|
|
|
Examples:
|
|
|
|
Input: A[] = { 6, 4, 12, 10, 22, 54, 32, 42, 21, 11}
|
|
Output:
|
|
Pairs : ( 4, 12) ( 6, 10) have sum : 16
|
|
Pairs : ( 10, 22) ( 21, 11) have sum : 32
|
|
Pairs : ( 12, 21) ( 22, 11) have sum : 33
|
|
Pairs : ( 22, 21) ( 32, 11) have sum : 43
|
|
Pairs : ( 32, 21) ( 42, 11) have sum : 53
|
|
Pairs : ( 12, 42) ( 22, 32) have sum : 54
|
|
Pairs : ( 10, 54) ( 22, 42) have sum : 64
|
|
|
|
Input:A[]= { 4, 23, 65, 67, 24, 12, 86}
|
|
Output:
|
|
Pairs : ( 4, 86) ( 23, 67) have sum : 90
|
|
"""
|
|
def main() -> None:
|
|
argc = len(sys.argv)
|
|
argv = sys.argv
|
|
|
|
# Read input from the file and process the data
|
|
try:
|
|
if argc != 2:
|
|
raise ValueError("Invalid input. You need to provide a single path to the input file. \n Ex.: `./solution.py ./input1.txt`")
|
|
|
|
input_data = read_input(argv[1])
|
|
print_pairs_with_same_sum(input_data)
|
|
except ValueError as e:
|
|
print(f"Error: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
def read_input(input_file: str) -> List[int]:
|
|
""" Reads the input file and returns a list of integers. """
|
|
try:
|
|
with open(input_file, "r") as file:
|
|
lst = file.readline().split(',')
|
|
parsed = [int(x.strip()) for x in lst]
|
|
return parsed
|
|
except Exception as e:
|
|
raise ValueError(f"Failed to read or parse the file: {e}")
|
|
|
|
def print_pairs_with_same_sum(arr: List[int]) -> None:
|
|
"""
|
|
Solution to the problem. Since performance is required it's in one method, but could be separated:
|
|
1). Calculate the sums into a hashmap and add the pairs
|
|
2). print the result
|
|
"""
|
|
|
|
# Not a valid array
|
|
if len(arr) < 2:
|
|
raise ValueError("No pairs can be formed from the input file.")
|
|
|
|
sum_map = defaultdict(list)
|
|
|
|
# Check for duplicate pairs.
|
|
seen_pairs = set()
|
|
|
|
n = len(arr)
|
|
|
|
for i in range(n):
|
|
# Time Complexity (O(n^2)), as we have n(n-1)/2 for the second loop.
|
|
for j in range(i + 1, n):
|
|
current_sum = arr[i] + arr[j]
|
|
|
|
# In order to follow the provided output, I must not sort the values of the pair (eg. ( 12, 21) ( 22, 11) have sum : 33)
|
|
# however in case of [12, 21, 12] this will output (12,21) (21,12), since we have a second 12. If this is not
|
|
# to be considered unique pair, then we must reverse the tuple and check if it really is unique.
|
|
pair = tuple((arr[i], arr[j]))
|
|
reversed_pair = tuple((arr[j], arr[i]))
|
|
|
|
# The check for reversed pairs.
|
|
if pair not in seen_pairs and reversed_pair not in seen_pairs:
|
|
|
|
# This will output nothing for [2,2,2,2]. Depending on the requirements we can store the pair using indices,
|
|
# then the result would be:
|
|
# (A[0],A[1]) (A[0],A[2]) (A[0],A[3]) (A[1],A[2]) (A[1],A[3]) (A[2],A[3]) - sum: 4
|
|
# And we will not need the seen_pairs set.
|
|
sum_map[current_sum].append(pair)
|
|
seen_pairs.add(pair)
|
|
|
|
# This is required to follow the example output, as it is presented as sorted by sum in the task description.
|
|
# We can skip the sorting if this is not really part of the requiremetns.
|
|
for sum_val in sorted(sum_map.keys()):
|
|
pairs = sum_map[sum_val]
|
|
|
|
if len(pairs) > 1:
|
|
pairs.sort()
|
|
|
|
print(f"Pairs : ", end="")
|
|
for pair in pairs:
|
|
print(f"( {pair[0]}, {pair[1]})", end=" ")
|
|
print(f"have sum : {sum_val}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |