class ThreeSum: def __init__(self): self.two_sum_obj = TwoSum() def twoSum(self, inputs, sum_for_comparison): # not to access any input element twice # todo: extend this function to deal with non-unique inputs, additional data structure to store counts of uniques and computation changes # exactly one solution # integers assert inputs.dtype == np.int hash_table = {} for curr_idx, curr_input in enumerate(inputs): complement_curr_input = sum_for_comparison - curr_input if complement_curr_input in hash_table: assert curr_idx != hash_table[complement_curr_input] return hash_table[complement_curr_input], curr_idx hash_table[curr_input] = curr_idx return None, None def threeSum(self, inputs): # not to access any input element twice # integers # assert inputs.dtype == np.int all_tuples = [] for curr_idx, curr_input in enumerate(inputs): complement_curr_input = -curr_input inputs_complement = np.concatenate( (inputs[:curr_idx], inputs[curr_idx + 1:])) curr_idx2, curr_idx3 = self.two_sum_obj.twoSum( inputs=inputs_complement, sum_for_comparison=complement_curr_input, ) if curr_idx2 is None: assert curr_idx3 is None continue if curr_idx2 >= curr_idx: curr_idx2 += 1 if curr_idx3 >= curr_idx: curr_idx3 += 1 curr_tuple = [ inputs[curr_idx], inputs[curr_idx2], inputs[curr_idx3], ] curr_tuple.sort() if curr_tuple not in all_tuples: all_tuples.append(curr_tuple) return all_tuples
def test_WithProperValues_ShouldReturnCorrectIndices(self): # arrange input = [2, 7, 11, 15] target = 9 expected_output = [ 0, 1 ] # act actual_output = TwoSum().two_sum_solver(input, target) # assert self.assertListEqual(expected_output, actual_output)
def test_WithNoAnswer_ShouldReturn00(self): # arrange input = [2,3,4] target = 9 expected_output = [0, 0] # act actual_output = TwoSum().two_sum_solver(input, target) # assert self.assertListEqual(expected_output, actual_output)
def test_WithFewInputs_ShouldReturnNone(self): # arrange input = [2] target = 9 expected_output = None # act actual_output = TwoSum().two_sum_solver(input, target) # assert self.assertEqual(expected_output, actual_output),
class TestTwoSum(unittest.TestCase): def setUp(self): self.two_sum = TwoSum() def tearDown(self): del self.two_sum def test_twosum_should_return_empty_when_input_is_None(self): self.assertEqual(self.two_sum.two_sum(None, 3), []) def test_twosum_should_return_empty_when_input_isempty(self): self.assertEqual(self.two_sum.two_sum([], 3), []) def test_twosum_should_raise_exception_when_target_can_not_be_achieved( self): with self.assertRaises(Exception): self.two_sum.two_sum([1, 5, 10], 3) def test_twosum_should_return_two_elements_which_sums_to_target(self): res = sum(self.two_sum.two_sum([1, 5, 10, 2], 3)) self.assertEqual(res, 3)
def setUp(self): self.two_sum = TwoSum()
def test_two_sum(self): self.assertEqual([0, 1], TwoSum.two_sum(nums=[2, 7, 11, 15], target=9))
def __init__(self): self.two_sum_obj = TwoSum()