# python3 program for the above approach. # Boolean array to check if elements # represented by a bitmask(subset) # can be split into two non-empty groups # having equal sum. canSplit = [0 for _ in range(1 << 20)] # Map to store sum of subsets # and find if there is a subset # with the current sum. mp = {} # Vector of vector to store # all the bitmasks having the # same sum together. subsets = [[] for _ in range(1 << 20)] # Variable to count subsets # having unique sums. ID = 0 # Function to generate all possible # subsets from first half # of the array. def makeSubsets1(i, N, sum, mask, Arr): global canSplit, mp, subsets, ID # If first half of the array # is traversed. if (i == N): # If none of the previously formed # subsets have the same sum # as the current subset. if (not sum in mp): # Increase ID by 1 as the # subsets having a unique # sum value has increased by 1. ID += 1 # Assign the value of sum to ID. mp[sum] = ID # Retrieve the subset number # having this sum. id = mp[sum] # Add the bitmask to the vector # of this particular subset id. subsets[id].append(mask) return # Exclude the current element # from the subset makeSubsets1(i + 1, N, sum, mask, Arr) # Include the current element # to the first group of the subset. makeSubsets1(i + 1, N, sum + Arr[i], mask | (1 << i), Arr) # Include the current element # to the second group of the subset. makeSubsets1(i + 1, N, sum - Arr[i], mask | (1 << i), Arr) # Function to generate all possible # subsets from second half of array. def makeSubsets2(i, N, sum, mask, Arr): global canSplit, mp, subsets, ID # If the second half # of the array is traversed. if (i == N): # If the current subset sum has # occurred before in the # first part of the array, then the # combined subset from both halves # of the array forms a valid subset if (sum in mp): # Iterate through all the bitmasks # from the first part of the array # having the same current sum. for num in subsets[mp[sum]]: # Mark the bitwise OR # of both subsets as TRUE. canSplit[num | mask] = 1 return # Exclude the current element # from the subset. makeSubsets2(i + 1, N, sum, mask, Arr) # Include the current element # to the second group of the subset. makeSubsets2(i + 1, N, sum + Arr[i], mask | (1 << i), Arr) # Include the current element # to the first group of the subset. makeSubsets2(i + 1, N, sum - Arr[i], mask | (1 << i), Arr) # Utility function to find all subsets from both halves of # the array. def UtilCountOfSubsets(N, Arr): global canSplit, mp, subsets, ID # Split the array into two parts. mid = N // 2 # Function calls makeSubsets1(0, mid, 0, 0, Arr) makeSubsets2(mid, N, 0, 0, Arr) ans = 0 # Iterate through all bitmasks # from 1 to 2^N - 1. for i in range(1, 1 << N): # If canSplit[i] is true, # increase the answer by 1. ans += canSplit[i] # Return the answer. return ans # Driver code if __name__ == "__main__": # Input Array Arr = [2, 3, 4, 5] # Size of array N = len(Arr) print(UtilCountOfSubsets(N, Arr)) # This code is contributed by rakeshsahni