Skip to content

Commit a7748f9

Browse files
committed
feat(math, negabinary numbers): adding two negabinary numbers
1 parent 63bc9eb commit a7748f9

3 files changed

Lines changed: 162 additions & 0 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Adding Two Negabinary Numbers
2+
3+
Given two numbers arr1 and arr2 in base -2, return the result of adding them together.
4+
5+
Each number is given in array format: as an array of 0s and 1s, from most significant bit to least significant bit.
6+
For example, arr = [1,1,0,1] represents the number (-2)^3 + (-2)^2 + (-2)^0 = -3. A number arr in array, format is also
7+
guaranteed to have no leading zeros: either arr == [0] or arr[0] == 1.
8+
9+
Return the result of adding arr1 and arr2 in the same format: as an array of 0s and 1s with no leading zeros.
10+
11+
## Examples
12+
13+
Example 1:
14+
```text
15+
Input: arr1 = [1,1,1,1,1], arr2 = [1,0,1]
16+
Output: [1,0,0,0,0]
17+
Explanation: arr1 represents 11, arr2 represents 5, the output represents 16.
18+
```
19+
20+
Example 2:
21+
```text
22+
Input: arr1 = [0], arr2 = [0]
23+
Output: [0]
24+
```
25+
26+
Example 3:
27+
```text
28+
Input: arr1 = [0], arr2 = [1]
29+
Output: [1]
30+
```
31+
32+
## Constraints
33+
34+
- 1 <= arr1.length, arr2.length <= 1000
35+
- arr1[i] and arr2[i] are 0 or 1
36+
- arr1 and arr2 have no leading zeros
37+
38+
## Topics
39+
40+
- Array
41+
- Math
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from typing import List
2+
3+
4+
def add_negabinary(arr1: List[int], arr2: List[int]) -> List[int]:
5+
# Initialize pointers to the least significant bits(rightmost elements)
6+
index_1, index_2 = len(arr1) - 1, len(arr2) - 1
7+
8+
# Initialize carry value for addition
9+
carry = 0
10+
11+
# Result to store the sum digits
12+
result = []
13+
14+
# Process digits from right to left, including any remaining carry
15+
while index_1 >= 0 or index_2 >= 0 or carry != 0:
16+
# Get current digit from arr1, or 0 if we've exhausted arr1
17+
digit_1 = 0 if index_1 < 0 else arr1[index_1]
18+
19+
# Get current digit from arr2, or 0 if we've exhausted arr2
20+
digit_2 = 0 if index_2 < 0 else arr2[index_2]
21+
22+
# Calculate sum of current position including carry
23+
current_sum = digit_1 + digit_2 + carry
24+
25+
# Reset carry for next iteration
26+
carry = 0
27+
28+
# Handle negabinary addition rules
29+
if current_sum >= 2:
30+
# If sum is 2 or more, subtract 2 and set negative carry
31+
current_sum -= 2
32+
carry = -1
33+
elif current_sum == -1:
34+
# If sum is -1, set digit to 1 and positive carry
35+
current_sum = 1
36+
carry = 1
37+
38+
# Append the computed digit to result
39+
result.append(current_sum)
40+
41+
# Move pointest to the next more significant bits
42+
index_1 -= 1
43+
index_2 -= 1
44+
45+
# Remove leading zeros from the result (except if result is just [0]
46+
while len(result) > 1 and result[-1] == 0:
47+
result.pop()
48+
49+
# Reverse the result since we built it from least to most significant
50+
return result[::-1]
51+
52+
53+
def add_negabinary_2(arr1: List[int], arr2: List[int]) -> List[int]:
54+
arr1 = arr1[::-1]
55+
arr2 = arr2[::-1]
56+
57+
max_len = max(len(arr1), len(arr2))
58+
59+
result = []
60+
carry = 0
61+
62+
i = 0
63+
while i < max_len or carry != 0:
64+
bit1 = arr1[i] if i < len(arr1) else 0
65+
bit2 = arr2[i] if i < len(arr2) else 0
66+
67+
total = bit1 + bit2 + carry
68+
69+
if total >= 0:
70+
result.append(total % 2)
71+
carry = -(total // 2)
72+
else:
73+
result.append(1)
74+
carry = 1
75+
76+
i += 1
77+
78+
while len(result) > 1 and result[-1] == 0:
79+
result.pop()
80+
81+
return result[::-1]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import unittest
2+
from typing import List
3+
from parameterized import parameterized
4+
from utils.test_utils import custom_test_name_func
5+
from pymath.adding_two_negabinary_numbers import add_negabinary, add_negabinary_2
6+
7+
ADD_TWO_NEGABINARY_NUMBERS_TEST_CASES = [
8+
([0], [0], [0]),
9+
([0], [1], [1]),
10+
([1], [1], [1, 1, 0]),
11+
([1, 0], [1], [1, 1]),
12+
([1, 1, 1, 1, 1], [1, 0, 1], [1, 0, 0, 0, 0]),
13+
([1, 0, 0], [0], [1, 0, 0]),
14+
([1, 1, 0], [1, 0, 1], [1, 1, 0, 1, 1]),
15+
([1, 1], [1], [0]),
16+
]
17+
18+
19+
class AddTwoNegabinaryNumbersTestCase(unittest.TestCase):
20+
@parameterized.expand(
21+
ADD_TWO_NEGABINARY_NUMBERS_TEST_CASES, name_func=custom_test_name_func
22+
)
23+
def test_add_two_negabinary_numbers(
24+
self, arr1: List[int], arr2: List[int], expected: List[int]
25+
):
26+
actual = add_negabinary(arr1, arr2)
27+
self.assertEqual(expected, actual)
28+
29+
@parameterized.expand(
30+
ADD_TWO_NEGABINARY_NUMBERS_TEST_CASES, name_func=custom_test_name_func
31+
)
32+
def test_add_two_negabinary_numbers_2(
33+
self, arr1: List[int], arr2: List[int], expected: List[int]
34+
):
35+
actual = add_negabinary_2(arr1, arr2)
36+
self.assertEqual(expected, actual)
37+
38+
39+
if __name__ == "__main__":
40+
unittest.main()

0 commit comments

Comments
 (0)