Ejemplo n.º 1
0
    def test_n_sum(self):
        self.assertEqual(n_sum(2, [-3, 5, 2, 3, 8, -9], 6), [])  # noqa: E501
        self.assertEqual(n_sum(3, [-5, -4, -3, -2, -1, 0, 1, 2, 3], 0),
                         sorted([[-5, 2, 3], [-2, 0, 2], [-4, 1,
                                                          3], [-3, 1, 2],
                                 [-1, 0, 1], [-2, -1, 3], [-3, 0,
                                                           3]]))  # noqa: E501
        self.assertEqual(n_sum(3, [-1, 0, 1, 2, -1, -4], 0),
                         sorted([[-1, -1, 2], [-1, 0, 1]]))  # noqa: E501
        self.assertEqual(n_sum(4, [1, 0, -1, 0, -2, 2], 0),
                         sorted([[-2, -1, 1, 2], [-2, 0, 0, 2],
                                 [-1, 0, 0, 1]]))  # noqa: E501
        self.assertEqual(
            n_sum(4, [
                7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 6, 4, -3, -2
            ], 10),
            sorted([[-6, 2, 7, 7], [-6, 3, 6, 7], [-6, 4, 5, 7], [-6, 4, 6, 6],
                    [-5, 1, 7, 7], [-5, 2, 6, 7], [-5, 3, 5, 7], [-5, 3, 6, 6],
                    [-5, 4, 4, 7], [-5, 4, 5, 6], [-4, 0, 7, 7], [-4, 1, 6, 7],
                    [-4, 2, 5, 7], [-4, 2, 6, 6], [-4, 3, 4, 7], [-4, 3, 5, 6],
                    [-4, 4, 4, 6], [-3, -1, 7, 7], [-3, 0, 6,
                                                    7], [-3, 1, 5, 7],
                    [-3, 1, 6, 6], [-3, 2, 4, 7], [-3, 2, 5, 6], [-3, 3, 4, 6],
                    [-3, 4, 4, 5], [-2, -2, 7, 7], [-2, -1, 6,
                                                    7], [-2, 0, 5, 7],
                    [-2, 0, 6, 6], [-2, 1, 4, 7], [-2, 1, 5, 6], [-2, 2, 3, 7],
                    [-2, 2, 4, 6], [-2, 3, 4, 5], [-1, 0, 4, 7], [-1, 0, 5, 6],
                    [-1, 1, 3, 7], [-1, 1, 4, 6], [-1, 2, 3, 6], [-1, 2, 4, 5],
                    [-1, 3, 4, 4], [0, 1, 2, 7], [0, 1, 3, 6], [0, 1, 4, 5],
                    [0, 2, 3, 5], [0, 2, 4, 4], [1, 2, 3, 4]]))  # noqa: E501

        self.assertEqual(
            n_sum(
                2,
                [[-3, 0], [-2, 1], [2, 2], [3, 3], [8, 4], [-9, 5]],
                0,  # noqa: E501
                sum_closure=lambda a, b: a[0] + b[0]),  # noqa: E501
            [[[-3, 0], [3, 3]], [[-2, 1], [2, 2]]])  # noqa: E501
        self.assertEqual(
            n_sum(
                2,
                [[-3, 0], [-2, 1], [2, 2], [3, 3], [8, 4], [-9, 5]],
                [0, 3],  # noqa: E501
                sum_closure=lambda a, b: [a[0] + b[0], a[1] + b[1]
                                          ],  # noqa: E501
                same_closure=lambda a, b: a[0] == b[0] and a[1] == b[1]
            ),  # noqa: E501
            [[[-3, 0], [3, 3]], [[-2, 1], [2, 2]]])  # noqa: E501
        self.assertEqual(
            n_sum(
                2,
                [[-3, 0], [-2, 1], [2, 2], [3, 3], [8, 4], [-9, 5]],
                -5,  # noqa: E501
                sum_closure=lambda a, b: [a[0] + b[1], a[1] + b[0]
                                          ],  # noqa: E501
                compare_closure=lambda a, b: -1 if a[0] < b else 1
                if a[0] > b else 0),  # noqa: E501
            [[[-9, 5], [8, 4]]])  # noqa: E501
Ejemplo n.º 2
0
    def test_n_sum(self):
        self.assertEqual(n_sum(2, [-3, 5, 2, 3, 8, -9], 6), [])  # noqa: E501
        self.assertEqual(n_sum(3, [-5, -4, -3, -2, -1, 0, 1, 2, 3], 0), sorted([[-5,2,3],[-2,0,2],[-4,1,3],[-3,1,2],[-1,0,1],[-2,-1,3],[-3,0,3]]))  # noqa: E501
        self.assertEqual(n_sum(3, [-1,0,1,2,-1,-4], 0), sorted([[-1,-1,2],[-1,0,1]]))  # noqa: E501
        self.assertEqual(n_sum(4, [1, 0, -1, 0, -2, 2], 0), sorted([[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]))  # noqa: E501
        self.assertEqual(n_sum(4, [7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 6, 4, -3, -2], 10), sorted([[-6, 2, 7, 7], [-6, 3, 6, 7], [-6, 4, 5, 7], [-6, 4, 6, 6], [-5, 1, 7, 7], [-5, 2, 6, 7], [-5, 3, 5, 7], [-5, 3, 6, 6], [-5, 4, 4, 7], [-5, 4, 5, 6], [-4, 0, 7, 7], [-4, 1, 6, 7], [-4, 2, 5, 7], [-4, 2, 6, 6], [-4, 3, 4, 7], [-4, 3, 5, 6], [-4, 4, 4, 6], [-3, -1, 7, 7], [-3, 0, 6, 7], [-3, 1, 5, 7], [-3, 1, 6, 6], [-3, 2, 4, 7], [-3, 2, 5, 6], [-3, 3, 4, 6], [-3, 4, 4, 5], [-2, -2, 7, 7], [-2, -1, 6, 7], [-2, 0, 5, 7], [-2, 0, 6, 6], [-2, 1, 4, 7], [-2, 1, 5, 6], [-2, 2, 3, 7], [-2, 2, 4, 6], [-2, 3, 4, 5], [-1, 0, 4, 7], [-1, 0, 5, 6], [-1, 1, 3, 7], [-1, 1, 4, 6], [-1, 2, 3, 6], [-1, 2, 4, 5], [-1, 3, 4, 4], [0, 1, 2, 7], [0, 1, 3, 6], [0, 1, 4, 5], [0, 2, 3, 5], [0, 2, 4, 4], [1, 2, 3, 4]]))  # noqa: E501

        self.assertEqual(n_sum(2, [[-3, 0], [-2, 1], [2, 2], [3, 3], [8, 4], [-9, 5]], 0,  # noqa: E501
                               sum_closure=lambda a, b: a[0] + b[0]),  # noqa: E501
                         [[[-3, 0], [3, 3]], [[-2, 1], [2, 2]]])  # noqa: E501
        self.assertEqual(n_sum(2, [[-3, 0], [-2, 1], [2, 2], [3, 3], [8, 4], [-9, 5]], [0, 3],  # noqa: E501
                               sum_closure=lambda a, b: [a[0] + b[0], a[1] + b[1]],  # noqa: E501
                               same_closure=lambda a, b: a[0] == b[0] and a[1] == b[1]),  # noqa: E501
                         [[[-3, 0], [3, 3]], [[-2, 1], [2, 2]]])  # noqa: E501
        self.assertEqual(n_sum(2, [[-3, 0], [-2, 1], [2, 2], [3, 3], [8, 4], [-9, 5]], -5,  # noqa: E501
                               sum_closure=lambda a, b: [a[0] + b[1], a[1] + b[0]],  # noqa: E501
                               compare_closure=lambda a, b: -1 if a[0] < b else 1 if a[0] > b else 0),  # noqa: E501
                         [[[-9, 5], [8, 4]]])  # noqa: E501
Ejemplo n.º 3
0
    def n_sum(n, nums, target):
        if n == 2:  # want answers with only 2 terms? easy!
            results = two_sum(nums, target)
        else:
            results = []
            prev_num = None
            for index, num in enumerate(nums):
                if prev_num is not None and \
                        same_closure(prev_num, num):
                    continue

                prev_num = num
                n_minus1_results = (
                    n_sum(  # recursive call
                        n - 1,  # a
                        nums[index + 1:],  # b
                        target - num  # c
                    )  # x = n_sum( a, b, c )
                )  # n_minus1_results = x

                n_minus1_results = (append_elem_to_each_list(
                    num, n_minus1_results))
                results += n_minus1_results
        return union(results)
Ejemplo n.º 4
0
def n_sum(n, nums, target, **kv):
    """
    n: int
    nums: list[object]
    target: object
    sum_closure: function, optional
        Given two elements of nums, return sum of both.
    compare_closure: function, optional
        Given one object of nums and target, return -1, 1, or 0.
    same_closure: function, optional
        Given two object of nums, return bool.
    return: list[list[object]]

    Note:
    1. type of sum_closure's return should be same
       as type of compare_closure's first param
    """
    def sum_closure_default(a, b):
        return a + b

    def compare_closure_default(num, target):
        """ above, below, or right on? """
        if num < target:
            return -1
        elif num > target:
            return 1
        else:
            return 0

    def same_closure_default(a, b):
        return a == b

    def n_sum(n, nums, target):
        if n == 2:  # want answers with only 2 terms? easy!
            results = two_sum(nums, target)
        else:
            results = []
            prev_num = None
            for index, num in enumerate(nums):
                if prev_num is not None and \
                        same_closure(prev_num, num):
                    continue

                prev_num = num
                n_minus1_results = (
                    n_sum(  # recursive call
                        n - 1,  # a
                        nums[index + 1:],  # b
                        target - num  # c
                    )  # x = n_sum( a, b, c )
                )  # n_minus1_results = x

                n_minus1_results = (append_elem_to_each_list(
                    num, n_minus1_results))
                results += n_minus1_results
        return union(results)

    def two_sum(nums, target):
        nums.sort()
        lt = 0
        rt = len(nums) - 1
        results = []
        while lt < rt:
            sum_ = sum_closure(nums[lt], nums[rt])
            flag = compare_closure(sum_, target)
            if flag == -1:
                lt += 1
            elif flag == 1:
                rt -= 1
            else:
                results.append(sorted([nums[lt], nums[rt]]))
                lt += 1
                rt -= 1
                while (lt < len(nums)
                       and same_closure(nums[lt - 1], nums[lt])):
                    lt += 1
                while (0 <= rt and same_closure(nums[rt], nums[rt + 1])):
                    rt -= 1
        return results

    def append_elem_to_each_list(elem, container):
        results = []
        for elems in container:
            elems.append(elem)
            results.append(sorted(elems))
        return results

    def union(duplicate_results):
        results = []

        if len(duplicate_results) != 0:
            duplicate_results.sort()
            results.append(duplicate_results[0])
            for result in duplicate_results[1:]:
                if results[-1] != result:
                    results.append(result)

        return results

    sum_closure = kv.get('sum_closure', sum_closure_default)
    same_closure = kv.get('same_closure', same_closure_default)
    compare_closure = kv.get('compare_closure', compare_closure_default)
    nums.sort()
    return n_sum(n, nums, target)
Ejemplo n.º 5
0
            def compare(num, target):
                if num[0] < target:
                    return -1
                elif if num[0] > target:
                    return 1
                else:
                    return 0
        return [[-9, 5], [8, 4]]
(TL:DR) because -9 + 4 = -5
"""
from algorithms.arrays import n_sum
n = 4
a = [1, 0, -1, 0, -2, 2]
target = 0

print(n_sum(n, a, target))


def n_sum(n, nums, target, **kv):
    """
    n: int
    nums: list[object]
    target: object
    sum_closure: function, optional
        Given two elements of nums, return sum of both.
    compare_closure: function, optional
        Given one object of nums and target, return -1, 1, or 0.
    same_closure: function, optional
        Given two object of nums, return bool.
    return: list[list[object]]