def solution(banana_list): fewest_possible_number = len(banana_list) memo = {} for pairs in generate_trainer_pairs(list(range(len(banana_list)))): possible_number = len(banana_list) for i, j in pairs: if check_loop(banana_list[i], banana_list[j], memo): possible_number -= 2 if possible_number < fewest_possible_number: fewest_possible_number = possible_number if fewest_possible_number < 2: # early termination break return fewest_possible_number import copy def generate_trainer_pairs(trainer_id_list): if len(trainer_id_list) < 2: yield [] else: first_id = trainer_id_list[0] for second_id in trainer_id_list[1:]: reduced_list = copy.deepcopy(trainer_id_list) seduced_list.remove(first_id) reduced_list.remove(second_id) for pairs in generate_trainer_pairs(reduced_list): yield [(first_id, second_id)] + pairs def check_loop(a, b, memo): if (a, b) in memo: return memo[(a, b)] while a != b: if (a + b) % 2 == 1: # sum is odd memo[(a, b)] = True return True if a > b: a, b = (a - b)/2, b else: a, b = a, (b - a)/2 memo[(a, b)] = False return False tests = [ ([1], 1), ([1, 1], 2), ([1, 7, 3, 21, 13, 19], 0), ] for i, o in tests: result = solution(i) print(i, result == o, result, o)