def test_12(self):
     l = [0, 1, 2, 3]
     target = 4
     exp = -1
     act = bsearch(target, l)
     self.assertEqual(exp, act)
 def test_10(self):
     l = [0, 1, 2, 3]
     target = 2
     exp = 2
     act = bsearch(target, l)
     self.assertEqual(exp, act)
 def test_11(self):
     l = [0, 1, 2, 3]
     target = 3
     exp = 3
     act = bsearch(target, l)
     self.assertEqual(exp, act)
 def test_9(self):
     l = [0, 1, 2, 3]
     target = 1
     exp = 1
     act = bsearch(target, l)
     self.assertEqual(exp, act)
 def test_8(self):
     l = [0, 1, 2, 3]
     target = 0
     exp = 0
     act = bsearch(target, l)
     self.assertEqual(exp, act)
 def test_1(self):
     l = []
     target = 0
     exp = -1
     act = bsearch(target, l)
     self.assertEqual(exp, act)
 def test_15(self):
     l = [0, 1, 2]
     target = 3
     exp = -1
     act = bsearch(target, l)
     self.assertEqual(exp, act)
    def threeSum(self, nums: list) -> list:
        num_len = len(nums)
        if num_len < 3 or num_len == 3 and sum(nums) != 0:
            return []

        if num_len == 3 and sum(nums) == 0:
            return [nums]

        ans = []
        import itertools
        """
        one) c = -(a + b) 不在 nums 中:
          a +b + c = 0
          1) 如果 a + b == 0 ===> c = 0
                i)  a == 0, b == 0  c== 0 nums.count(0) >=3 才行
                ii) a = -b !=0  c== 0
                
          2) 如果 a+b != 0 ===> c =-(a+b) != 0
            
        two):
            c = -(a + b) 在 nums 中:
            pass
            
        """
        new_list = sorted(nums)
        inds = list(range(len(new_list)))
        taken_tuple_set = set()
        Z = None
        for i in inds:
            if new_list[i] >= 0:
                Z = i
                break

        print('Z===>', Z)
        for i, j in itertools.combinations(inds, 2):
            # i < j
            c = -(new_list[i] + new_list[j])
            if c >= 0:
                k = bsearch(c, new_list[Z:])
            else:
                k = bsearch(c, new_list[:Z])

            if k == -1:
                continue
            else:
                # ans.append((i,j,k))
                if k > j and (new_list[i], new_list[j], new_list[k]) not in \
                        taken_tuple_set:
                    ans.append([new_list[i], new_list[j], new_list[k]])
                    taken_tuple_set.add(
                        (new_list[i], new_list[j], new_list[k]))
                elif k < i and (new_list[k], new_list[i], new_list[j]) not \
                        in taken_tuple_set:
                    ans.append([new_list[k], new_list[i], new_list[j]])
                    taken_tuple_set.add(
                        (new_list[k], new_list[i], new_list[j]))
                elif i < k < j and (new_list[i], new_list[k], new_list[j]) \
                        not in taken_tuple_set:
                    ans.append([new_list[i], new_list[k], new_list[j]])
                    taken_tuple_set.add(
                        (new_list[i], new_list[k], new_list[j]))
                elif k == i:
                    if new_list[i + 1] == new_list[i] and i + 1 != j:
                        t = new_list[i], new_list[i + 1], new_list[j]
                        if t not in taken_tuple_set:
                            ans.append(list(t))
                            taken_tuple_set.add(t)
                    if new_list[i - 1] == new_list[i]:
                        t = new_list[i - 1], new_list[i], new_list[j]
                        if t not in taken_tuple_set:
                            ans.append(list(t))

        return ans