Skip to content

Commit 01a7a75

Browse files
authored
Merge branch 'TheAlgorithms:master' into binary_operations
2 parents 1fcfc0a + ebe6693 commit 01a7a75

36 files changed

Lines changed: 620 additions & 251 deletions

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ repos:
5151
- id: validate-pyproject
5252

5353
- repo: https://github.com/pre-commit/mirrors-mypy
54-
rev: v1.5.1
54+
rev: v1.6.0
5555
hooks:
5656
- id: mypy
5757
args:

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@
532532
* [Logistic Regression](machine_learning/logistic_regression.py)
533533
* Loss Functions
534534
* [Binary Cross Entropy](machine_learning/loss_functions/binary_cross_entropy.py)
535+
* [Categorical Cross Entropy](machine_learning/loss_functions/categorical_cross_entropy.py)
535536
* [Huber Loss](machine_learning/loss_functions/huber_loss.py)
536537
* [Mean Squared Error](machine_learning/loss_functions/mean_squared_error.py)
537538
* [Mfcc](machine_learning/mfcc.py)

blockchain/diophantine_equation.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
8383
(1, -2, 3)
8484
8585
"""
86-
assert a >= 0 and b >= 0
86+
assert a >= 0
87+
assert b >= 0
8788

8889
if b == 0:
8990
d, x, y = a, 1, 0
@@ -92,7 +93,8 @@ def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
9293
x = q
9394
y = p - q * (a // b)
9495

95-
assert a % d == 0 and b % d == 0
96+
assert a % d == 0
97+
assert b % d == 0
9698
assert d == a * x + b * y
9799

98100
return (d, x, y)

boolean_algebra/imply_gate.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
An IMPLY Gate is a logic gate in boolean algebra which results to 1 if
3+
either input 1 is 0, or if input 1 is 1, then the output is 1 only if input 2 is 1.
4+
It is true if input 1 implies input 2.
5+
6+
Following is the truth table of an IMPLY Gate:
7+
------------------------------
8+
| Input 1 | Input 2 | Output |
9+
------------------------------
10+
| 0 | 0 | 1 |
11+
| 0 | 1 | 1 |
12+
| 1 | 0 | 0 |
13+
| 1 | 1 | 1 |
14+
------------------------------
15+
16+
Refer - https://en.wikipedia.org/wiki/IMPLY_gate
17+
"""
18+
19+
20+
def imply_gate(input_1: int, input_2: int) -> int:
21+
"""
22+
Calculate IMPLY of the input values
23+
24+
>>> imply_gate(0, 0)
25+
1
26+
>>> imply_gate(0, 1)
27+
1
28+
>>> imply_gate(1, 0)
29+
0
30+
>>> imply_gate(1, 1)
31+
1
32+
"""
33+
return int(input_1 == 0 or input_2 == 1)
34+
35+
36+
if __name__ == "__main__":
37+
print(imply_gate(0, 0))
38+
print(imply_gate(0, 1))
39+
print(imply_gate(1, 0))
40+
print(imply_gate(1, 1))

boolean_algebra/nimply_gate.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
An NIMPLY Gate is a logic gate in boolean algebra which results to 0 if
3+
either input 1 is 0, or if input 1 is 1, then it is 0 only if input 2 is 1.
4+
It is false if input 1 implies input 2. It is the negated form of imply
5+
6+
Following is the truth table of an NIMPLY Gate:
7+
------------------------------
8+
| Input 1 | Input 2 | Output |
9+
------------------------------
10+
| 0 | 0 | 0 |
11+
| 0 | 1 | 0 |
12+
| 1 | 0 | 1 |
13+
| 1 | 1 | 0 |
14+
------------------------------
15+
16+
Refer - https://en.wikipedia.org/wiki/NIMPLY_gate
17+
"""
18+
19+
20+
def nimply_gate(input_1: int, input_2: int) -> int:
21+
"""
22+
Calculate NIMPLY of the input values
23+
24+
>>> nimply_gate(0, 0)
25+
0
26+
>>> nimply_gate(0, 1)
27+
0
28+
>>> nimply_gate(1, 0)
29+
1
30+
>>> nimply_gate(1, 1)
31+
0
32+
"""
33+
return int(input_1 == 1 and input_2 == 0)
34+
35+
36+
if __name__ == "__main__":
37+
print(nimply_gate(0, 0))
38+
print(nimply_gate(0, 1))
39+
print(nimply_gate(1, 0))
40+
print(nimply_gate(1, 1))

ciphers/xor_cipher.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ def encrypt(self, content: str, key: int) -> list[str]:
3838
"""
3939

4040
# precondition
41-
assert isinstance(key, int) and isinstance(content, str)
41+
assert isinstance(key, int)
42+
assert isinstance(content, str)
4243

4344
key = key or self.__key or 1
4445

@@ -56,7 +57,8 @@ def decrypt(self, content: str, key: int) -> list[str]:
5657
"""
5758

5859
# precondition
59-
assert isinstance(key, int) and isinstance(content, list)
60+
assert isinstance(key, int)
61+
assert isinstance(content, list)
6062

6163
key = key or self.__key or 1
6264

@@ -74,7 +76,8 @@ def encrypt_string(self, content: str, key: int = 0) -> str:
7476
"""
7577

7678
# precondition
77-
assert isinstance(key, int) and isinstance(content, str)
79+
assert isinstance(key, int)
80+
assert isinstance(content, str)
7881

7982
key = key or self.__key or 1
8083

@@ -99,7 +102,8 @@ def decrypt_string(self, content: str, key: int = 0) -> str:
99102
"""
100103

101104
# precondition
102-
assert isinstance(key, int) and isinstance(content, str)
105+
assert isinstance(key, int)
106+
assert isinstance(content, str)
103107

104108
key = key or self.__key or 1
105109

@@ -125,7 +129,8 @@ def encrypt_file(self, file: str, key: int = 0) -> bool:
125129
"""
126130

127131
# precondition
128-
assert isinstance(file, str) and isinstance(key, int)
132+
assert isinstance(file, str)
133+
assert isinstance(key, int)
129134

130135
try:
131136
with open(file) as fin, open("encrypt.out", "w+") as fout:
@@ -148,7 +153,8 @@ def decrypt_file(self, file: str, key: int) -> bool:
148153
"""
149154

150155
# precondition
151-
assert isinstance(file, str) and isinstance(key, int)
156+
assert isinstance(file, str)
157+
assert isinstance(key, int)
152158

153159
try:
154160
with open(file) as fin, open("decrypt.out", "w+") as fout:

conversions/decimal_to_hexadecimal.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def decimal_to_hexadecimal(decimal: float) -> str:
5757
>>> decimal_to_hexadecimal(-256) == hex(-256)
5858
True
5959
"""
60-
assert type(decimal) in (int, float) and decimal == int(decimal)
60+
assert isinstance(decimal, (int, float))
61+
assert decimal == int(decimal)
6162
decimal = int(decimal)
6263
hexadecimal = ""
6364
negative = False
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from itertools import combinations
2+
3+
4+
def find_triplets_with_0_sum(nums: list[int]) -> list[list[int]]:
5+
"""
6+
Given a list of integers, return elements a, b, c such that a + b + c = 0.
7+
Args:
8+
nums: list of integers
9+
Returns:
10+
list of lists of integers where sum(each_list) == 0
11+
Examples:
12+
>>> find_triplets_with_0_sum([-1, 0, 1, 2, -1, -4])
13+
[[-1, -1, 2], [-1, 0, 1]]
14+
>>> find_triplets_with_0_sum([])
15+
[]
16+
>>> find_triplets_with_0_sum([0, 0, 0])
17+
[[0, 0, 0]]
18+
>>> find_triplets_with_0_sum([1, 2, 3, 0, -1, -2, -3])
19+
[[-3, 0, 3], [-3, 1, 2], [-2, -1, 3], [-2, 0, 2], [-1, 0, 1]]
20+
"""
21+
return [
22+
list(x)
23+
for x in sorted({abc for abc in combinations(sorted(nums), 3) if not sum(abc)})
24+
]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
Given an array of integers and an integer req_sum, find the number of pairs of array
5+
elements whose sum is equal to req_sum.
6+
7+
https://practice.geeksforgeeks.org/problems/count-pairs-with-given-sum5022/0
8+
"""
9+
from itertools import combinations
10+
11+
12+
def pairs_with_sum(arr: list, req_sum: int) -> int:
13+
"""
14+
Return the no. of pairs with sum "sum"
15+
>>> pairs_with_sum([1, 5, 7, 1], 6)
16+
2
17+
>>> pairs_with_sum([1, 1, 1, 1, 1, 1, 1, 1], 2)
18+
28
19+
>>> pairs_with_sum([1, 7, 6, 2, 5, 4, 3, 1, 9, 8], 7)
20+
4
21+
"""
22+
return len([1 for a, b in combinations(arr, 2) if a + b == req_sum])
23+
24+
25+
if __name__ == "__main__":
26+
from doctest import testmod
27+
28+
testmod()

data_structures/binary_tree/binary_search_tree_recursive.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import unittest
1313
from collections.abc import Iterator
1414

15+
import pytest
16+
1517

1618
class Node:
1719
def __init__(self, label: int, parent: Node | None) -> None:
@@ -78,7 +80,7 @@ def _put(self, node: Node | None, label: int, parent: Node | None = None) -> Nod
7880
node.right = self._put(node.right, label, node)
7981
else:
8082
msg = f"Node with label {label} already exists"
81-
raise Exception(msg)
83+
raise ValueError(msg)
8284

8385
return node
8486

@@ -95,14 +97,14 @@ def search(self, label: int) -> Node:
9597
>>> node = t.search(3)
9698
Traceback (most recent call last):
9799
...
98-
Exception: Node with label 3 does not exist
100+
ValueError: Node with label 3 does not exist
99101
"""
100102
return self._search(self.root, label)
101103

102104
def _search(self, node: Node | None, label: int) -> Node:
103105
if node is None:
104106
msg = f"Node with label {label} does not exist"
105-
raise Exception(msg)
107+
raise ValueError(msg)
106108
else:
107109
if label < node.label:
108110
node = self._search(node.left, label)
@@ -124,7 +126,7 @@ def remove(self, label: int) -> None:
124126
>>> t.remove(3)
125127
Traceback (most recent call last):
126128
...
127-
Exception: Node with label 3 does not exist
129+
ValueError: Node with label 3 does not exist
128130
"""
129131
node = self.search(label)
130132
if node.right and node.left:
@@ -179,7 +181,7 @@ def exists(self, label: int) -> bool:
179181
try:
180182
self.search(label)
181183
return True
182-
except Exception:
184+
except ValueError:
183185
return False
184186

185187
def get_max_label(self) -> int:
@@ -190,15 +192,15 @@ def get_max_label(self) -> int:
190192
>>> t.get_max_label()
191193
Traceback (most recent call last):
192194
...
193-
Exception: Binary search tree is empty
195+
ValueError: Binary search tree is empty
194196
195197
>>> t.put(8)
196198
>>> t.put(10)
197199
>>> t.get_max_label()
198200
10
199201
"""
200202
if self.root is None:
201-
raise Exception("Binary search tree is empty")
203+
raise ValueError("Binary search tree is empty")
202204

203205
node = self.root
204206
while node.right is not None:
@@ -214,15 +216,15 @@ def get_min_label(self) -> int:
214216
>>> t.get_min_label()
215217
Traceback (most recent call last):
216218
...
217-
Exception: Binary search tree is empty
219+
ValueError: Binary search tree is empty
218220
219221
>>> t.put(8)
220222
>>> t.put(10)
221223
>>> t.get_min_label()
222224
8
223225
"""
224226
if self.root is None:
225-
raise Exception("Binary search tree is empty")
227+
raise ValueError("Binary search tree is empty")
226228

227229
node = self.root
228230
while node.left is not None:
@@ -359,7 +361,7 @@ def test_put(self) -> None:
359361
assert t.root.left.left.parent == t.root.left
360362
assert t.root.left.left.label == 1
361363

362-
with self.assertRaises(Exception): # noqa: B017
364+
with pytest.raises(ValueError):
363365
t.put(1)
364366

365367
def test_search(self) -> None:
@@ -371,7 +373,7 @@ def test_search(self) -> None:
371373
node = t.search(13)
372374
assert node.label == 13
373375

374-
with self.assertRaises(Exception): # noqa: B017
376+
with pytest.raises(ValueError):
375377
t.search(2)
376378

377379
def test_remove(self) -> None:
@@ -517,7 +519,7 @@ def test_get_max_label(self) -> None:
517519
assert t.get_max_label() == 14
518520

519521
t.empty()
520-
with self.assertRaises(Exception): # noqa: B017
522+
with pytest.raises(ValueError):
521523
t.get_max_label()
522524

523525
def test_get_min_label(self) -> None:
@@ -526,7 +528,7 @@ def test_get_min_label(self) -> None:
526528
assert t.get_min_label() == 1
527529

528530
t.empty()
529-
with self.assertRaises(Exception): # noqa: B017
531+
with pytest.raises(ValueError):
530532
t.get_min_label()
531533

532534
def test_inorder_traversal(self) -> None:

0 commit comments

Comments
 (0)