StarterPeter
StarterPeter

Reputation: 35

How to optimise the program to solve RecursionError: maximum recursion

The aim of this program is to find all the integer pairs of three that are in range of 0 and 57 that can form a triangle. (I made the program for a Math problem)

import random
import time
dict = {}
current_list = []
key_num = 0
def main():
    global key_num
    a = random.randint(1, 57)
    b = random.randint(1, 57)
    c = random.randint(1, 57)
    if a + b > c and a + c > b and b + c > a:
        current_list.append(a)
        current_list.append(b)
        current_list.append(c)
        current_list.sort()
        for i in range(0, key_num):
            if dict[i] == current_list:
                main()
        dict.setdefault(key_num, current_list) 
        key_num += 1
        current_list.clear()
        print(str(key_num))
        print(dict)
        time.sleep(0.8)     
while True:
    main()

However, when I run it, there are two problems.

First, after a while program is launched, an error RecursionError: maximum recursion is displayed. For this, I have tried to set the limit higher to 10^5 but the program just crashed after a while.

Second, the dictionary isn't inputting any new items during the process.

I am not that experienced in python and thanks a lot if you would like to help.

Also, a + b > c and a + c > b and b + c > a is the criteria for an triangle: the sum of any two sides is bigger than the third side.

Upvotes: 2

Views: 90

Answers (1)

Sam Spade
Sam Spade

Reputation: 1486

Ok, so first of all, in general stack overflow questions should be condensed to the point that their answers can be useful to others.

Now, there are several problem with your code:

  1. you call main inside main. When you say:
if dict[i] == current_list:
    main()

what I think you mean is: if this set of integers has already been checked, go back to the beginning. But instead it runs the function main() again, this time inside of itself. What you should do instead is write:

if dict[i] == current_list:
    return
  1. You don't have an end condition. The code won't stop because there is no way for it to exit the loop. You need some way to determine when it is finished.

  2. dict.setdefault(key_num, current_list) has several issues. Number one is that the way you assign an item to a dictionary is: dict[key_num] = current_list. setdefault is a totally different thing and, while it somtimes produces the same result, it isn't the thing you are looking for.

  3. The next issue is that you clear current_list in the next line, which means the list that you just put into your dictionary is now an empty list.

My recommendation is to restructure the code into several for loops to check every combination:

identifiedSets = [];
for a in range(1, 57):
    for b in range(1, 57):
        for c in range(1, 57):
            if a + b > c and a + c > b and b + c > a:
                newList = [a, b, c]
                newList.sort();
                identifiedSets.append(str(newList))

print(str(identifiedSets))

This way you will iterate through every possible combination of numbers and, by storing the results as a list of strings, you can check if those strings have already been added to the list. Finally, printing the results is easy because the results are already strings.

Upvotes: 4

Related Questions