Skip to content

Commit 2c4bfe6

Browse files
authored
Merge branch 'TheAlgorithms:master' into master
2 parents a85b7da + c919579 commit 2c4bfe6

8 files changed

Lines changed: 147 additions & 39 deletions

File tree

DIRECTORY.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,6 @@
661661
* [Manhattan Distance](maths/manhattan_distance.py)
662662
* [Matrix Exponentiation](maths/matrix_exponentiation.py)
663663
* [Max Sum Sliding Window](maths/max_sum_sliding_window.py)
664-
* [Median Of Two Arrays](maths/median_of_two_arrays.py)
665664
* [Minkowski Distance](maths/minkowski_distance.py)
666665
* [Mobius Function](maths/mobius_function.py)
667666
* [Modular Division](maths/modular_division.py)

backtracking/all_permutations.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,42 @@ def create_state_space_tree(
2323
Creates a state space tree to iterate through each branch using DFS.
2424
We know that each state has exactly len(sequence) - index children.
2525
It terminates when it reaches the end of the given sequence.
26+
27+
:param sequence: The input sequence for which permutations are generated.
28+
:param current_sequence: The current permutation being built.
29+
:param index: The current index in the sequence.
30+
:param index_used: list to track which elements are used in permutation.
31+
32+
Example 1:
33+
>>> sequence = [1, 2, 3]
34+
>>> current_sequence = []
35+
>>> index_used = [False, False, False]
36+
>>> create_state_space_tree(sequence, current_sequence, 0, index_used)
37+
[1, 2, 3]
38+
[1, 3, 2]
39+
[2, 1, 3]
40+
[2, 3, 1]
41+
[3, 1, 2]
42+
[3, 2, 1]
43+
44+
Example 2:
45+
>>> sequence = ["A", "B", "C"]
46+
>>> current_sequence = []
47+
>>> index_used = [False, False, False]
48+
>>> create_state_space_tree(sequence, current_sequence, 0, index_used)
49+
['A', 'B', 'C']
50+
['A', 'C', 'B']
51+
['B', 'A', 'C']
52+
['B', 'C', 'A']
53+
['C', 'A', 'B']
54+
['C', 'B', 'A']
55+
56+
Example 3:
57+
>>> sequence = [1]
58+
>>> current_sequence = []
59+
>>> index_used = [False]
60+
>>> create_state_space_tree(sequence, current_sequence, 0, index_used)
61+
[1]
2662
"""
2763

2864
if index == len(sequence):

backtracking/all_subsequences.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,56 @@ def create_state_space_tree(
2222
Creates a state space tree to iterate through each branch using DFS.
2323
We know that each state has exactly two children.
2424
It terminates when it reaches the end of the given sequence.
25+
26+
:param sequence: The input sequence for which subsequences are generated.
27+
:param current_subsequence: The current subsequence being built.
28+
:param index: The current index in the sequence.
29+
30+
Example:
31+
>>> sequence = [3, 2, 1]
32+
>>> current_subsequence = []
33+
>>> create_state_space_tree(sequence, current_subsequence, 0)
34+
[]
35+
[1]
36+
[2]
37+
[2, 1]
38+
[3]
39+
[3, 1]
40+
[3, 2]
41+
[3, 2, 1]
42+
43+
>>> sequence = ["A", "B"]
44+
>>> current_subsequence = []
45+
>>> create_state_space_tree(sequence, current_subsequence, 0)
46+
[]
47+
['B']
48+
['A']
49+
['A', 'B']
50+
51+
>>> sequence = []
52+
>>> current_subsequence = []
53+
>>> create_state_space_tree(sequence, current_subsequence, 0)
54+
[]
55+
56+
>>> sequence = [1, 2, 3, 4]
57+
>>> current_subsequence = []
58+
>>> create_state_space_tree(sequence, current_subsequence, 0)
59+
[]
60+
[4]
61+
[3]
62+
[3, 4]
63+
[2]
64+
[2, 4]
65+
[2, 3]
66+
[2, 3, 4]
67+
[1]
68+
[1, 4]
69+
[1, 3]
70+
[1, 3, 4]
71+
[1, 2]
72+
[1, 2, 4]
73+
[1, 2, 3]
74+
[1, 2, 3, 4]
2575
"""
2676

2777
if index == len(sequence):
@@ -35,7 +85,7 @@ def create_state_space_tree(
3585

3686

3787
if __name__ == "__main__":
38-
seq: list[Any] = [3, 1, 2, 4]
88+
seq: list[Any] = [1, 2, 3]
3989
generate_all_subsequences(seq)
4090

4191
seq.clear()

bit_manipulation/binary_and_operator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def binary_and(a: int, b: int) -> str:
2626
>>> binary_and(0, 1.1)
2727
Traceback (most recent call last):
2828
...
29-
TypeError: 'float' object cannot be interpreted as an integer
29+
ValueError: Unknown format code 'b' for object of type 'float'
3030
>>> binary_and("0", "1")
3131
Traceback (most recent call last):
3232
...
@@ -35,8 +35,8 @@ def binary_and(a: int, b: int) -> str:
3535
if a < 0 or b < 0:
3636
raise ValueError("the value of both inputs must be positive")
3737

38-
a_binary = str(bin(a))[2:] # remove the leading "0b"
39-
b_binary = str(bin(b))[2:] # remove the leading "0b"
38+
a_binary = format(a, "b")
39+
b_binary = format(b, "b")
4040

4141
max_len = max(len(a_binary), len(b_binary))
4242

divide_and_conquer/power.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@ def actual_power(a: int, b: int):
22
"""
33
Function using divide and conquer to calculate a^b.
44
It only works for integer a,b.
5+
6+
:param a: The base of the power operation, an integer.
7+
:param b: The exponent of the power operation, a non-negative integer.
8+
:return: The result of a^b.
9+
10+
Examples:
11+
>>> actual_power(3, 2)
12+
9
13+
>>> actual_power(5, 3)
14+
125
15+
>>> actual_power(2, 5)
16+
32
17+
>>> actual_power(7, 0)
18+
1
519
"""
620
if b == 0:
721
return 1
@@ -13,6 +27,10 @@ def actual_power(a: int, b: int):
1327

1428
def power(a: int, b: int) -> float:
1529
"""
30+
:param a: The base (integer).
31+
:param b: The exponent (integer).
32+
:return: The result of a^b, as a float for negative exponents.
33+
1634
>>> power(4,6)
1735
4096
1836
>>> power(2,3)

machine_learning/loss_functions.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,40 @@ def smooth_l1_loss(y_true: np.ndarray, y_pred: np.ndarray, beta: float = 1.0) ->
629629
return np.mean(loss)
630630

631631

632+
def kullback_leibler_divergence(y_true: np.ndarray, y_pred: np.ndarray) -> float:
633+
"""
634+
Calculate the Kullback-Leibler divergence (KL divergence) loss between true labels
635+
and predicted probabilities.
636+
637+
KL divergence loss quantifies dissimilarity between true labels and predicted
638+
probabilities. It's often used in training generative models.
639+
640+
KL = Σ(y_true * ln(y_true / y_pred))
641+
642+
Reference: https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence
643+
644+
Parameters:
645+
- y_true: True class probabilities
646+
- y_pred: Predicted class probabilities
647+
648+
>>> true_labels = np.array([0.2, 0.3, 0.5])
649+
>>> predicted_probs = np.array([0.3, 0.3, 0.4])
650+
>>> kullback_leibler_divergence(true_labels, predicted_probs)
651+
0.030478754035472025
652+
>>> true_labels = np.array([0.2, 0.3, 0.5])
653+
>>> predicted_probs = np.array([0.3, 0.3, 0.4, 0.5])
654+
>>> kullback_leibler_divergence(true_labels, predicted_probs)
655+
Traceback (most recent call last):
656+
...
657+
ValueError: Input arrays must have the same length.
658+
"""
659+
if len(y_true) != len(y_pred):
660+
raise ValueError("Input arrays must have the same length.")
661+
662+
kl_loss = y_true * np.log(y_true / y_pred)
663+
return np.sum(kl_loss)
664+
665+
632666
if __name__ == "__main__":
633667
import doctest
634668

machine_learning/sequential_minimum_optimization.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,11 @@ def test_cancel_data():
463463
with open(r"cancel_data.csv", "w") as f:
464464
f.write(content)
465465

466-
data = pd.read_csv(r"cancel_data.csv", header=None)
466+
data = pd.read_csv(
467+
"cancel_data.csv",
468+
header=None,
469+
dtype={0: str}, # Assuming the first column contains string data
470+
)
467471

468472
# 1: pre-processing data
469473
del data[data.columns.tolist()[0]]

maths/median_of_two_arrays.py

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)