I have been given the following task to complete. I am not sure if my solution is the most efficient. Are you able to take a look and suggest any changes?
task:
An application that finds all pairs of natural numbers whose sum is 12. Once a number is used to create a pair it cannot be part of another pair.
Input values:
Set of N natural numbers with values from 0 to 12
[1,12,4,6,8,5,7,12,11,6,7,5,0]
Output Values:
Pairs of numbers that add up to 12. The pair can be returned in any order. The first number of the pair should be no greater than second. example:
[0,12],[1,11],[4,8],[6,6],[5,7],[6,6]
There are some technical requirements for solution:
- Remember about clean code.
- Think about the computational and memory complexity of the proposed solution.
- Try to solve the task in accordance with the object-oriented programming paradigm.
- data should be read and written from/to a text file. The file format is arbitrary.
my solution:
I would like to start by describing my solution. Due to the unknown number of elements in the input file, I wanted to avoid nested loops because I don't know if this will be a quick solution with several million elements. So all works as follows:
- Reading data from .txt files and converting values to int.
- Create a list containing all possible pairs that can occur. Here is the condition that the first number must be no greater than the second number.
- Based on the created pattern of pairs and counted elements from the input file count_pairs function creates a dictionary, where the key is the pair and the value is the number of occurrences of that pair.
- expand the grouped elements to a form that will be saved in the file.
- save to file Everything works fine, but I'm afraid I've overthought this solution and there is the easiest way to do it.
from collections import Counter
import re
def read_data_to_list(file_name: str) -> list:
file = open(file_name, "r")
file_content = file.read()
result = re.findall(r"\d+", file_content)
result = [int(element) for element in result]
return result
def possible_pairs(input_data: list, target_num: int) -> list:
input_set = set(input_data)
result = []
for element in list(input_set):
if target_num - element in input_set:
if element <= target_num - element:
result.append((element, target_num - element))
return result
def count_pairs(counted_elements: dict, possible_pairs_list: list) -> dict:
result = {}
for pair in possible_pairs_list:
if pair[0] == pair[1]:
occurring_pairs = int(counted_elements[pair[0]] // 2)
result.update({pair: occurring_pairs})
else:
occurance_first_element = counted_elements[pair[0]]
occurance_second_element = counted_elements[pair[1]]
occurring_pairs = min(occurance_first_element, occurance_second_element)
result.update({pair: occurring_pairs})
return result
def create_output_list(input_dict: dict) -> list:
result = []
for key, value in input_dict.items():
for each in range(value):
result.append(list(key))
return result
if __name__ == "__main__":
input_list = read_data_to_list("test.txt")
possible_pairs_list = possible_pairs(input_list, target_num=12)
count_elements = Counter(input_list)
all_pairs = count_pairs(count_elements, possible_pairs_list)
output = create_output_list(all_pairs)
with open("output.txt", "w") as file:
file.write(str(output))
```