Skip to content

Commit 7cf42d9

Browse files
authored
Merge branch 'TheAlgorithms:master' into time_period_simple_pendulum
2 parents d38f52c + eb17fcf commit 7cf42d9

File tree

188 files changed

+8284
-2730
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

188 files changed

+8284
-2730
lines changed

.github/ISSUE_TEMPLATE/feature_request.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ body:
66
attributes:
77
value: >
88
Before requesting please search [existing issues](https://github.com/TheAlgorithms/Python/labels/enhancement).
9+
Do not create issues to implement new algorithms as these will be closed.
910
Usage questions such as "How do I...?" belong on the
1011
[Discord](https://discord.gg/c7MnfGFGa6) and will be closed.
1112
1213
- type: textarea
1314
attributes:
1415
label: "Feature description"
1516
description: >
16-
This could be new algorithms, data structures or improving any existing
17-
implementations.
17+
This could include new topics or improving any existing implementations.
1818
validations:
1919
required: true

.github/pull_request_template.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* [ ] Add an algorithm?
66
* [ ] Fix a bug or typo in an existing algorithm?
7+
* [ ] Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
78
* [ ] Documentation change?
89

910
### Checklist:

.pre-commit-config.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ repos:
1616
- id: auto-walrus
1717

1818
- repo: https://github.com/astral-sh/ruff-pre-commit
19-
rev: v0.0.292
19+
rev: v0.1.1
2020
hooks:
2121
- id: ruff
2222

2323
- repo: https://github.com/psf/black
24-
rev: 23.9.1
24+
rev: 23.10.0
2525
hooks:
2626
- id: black
2727

@@ -46,12 +46,12 @@ repos:
4646
pass_filenames: false
4747

4848
- repo: https://github.com/abravalheri/validate-pyproject
49-
rev: v0.14
49+
rev: v0.15
5050
hooks:
5151
- id: validate-pyproject
5252

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

DIRECTORY.md

+83-52
Large diffs are not rendered by default.

arithmetic_analysis/README.md

-7
This file was deleted.

arithmetic_analysis/image_data/__init__.py

Whitespace-only changes.

arithmetic_analysis/newton_method.py

-54
This file was deleted.

arithmetic_analysis/newton_raphson.py

-46
This file was deleted.

arithmetic_analysis/newton_raphson_new.py

-83
This file was deleted.

backtracking/all_combinations.py

+38-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,40 @@
11
"""
22
In this problem, we want to determine all possible combinations of k
33
numbers out of 1 ... n. We use backtracking to solve this problem.
4-
Time complexity: O(C(n,k)) which is O(n choose k) = O((n!/(k! * (n - k)!)))
4+
5+
Time complexity: O(C(n,k)) which is O(n choose k) = O((n!/(k! * (n - k)!))),
56
"""
67
from __future__ import annotations
78

9+
from itertools import combinations
10+
11+
12+
def combination_lists(n: int, k: int) -> list[list[int]]:
13+
"""
14+
>>> combination_lists(n=4, k=2)
15+
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
16+
"""
17+
return [list(x) for x in combinations(range(1, n + 1), k)]
18+
819

920
def generate_all_combinations(n: int, k: int) -> list[list[int]]:
1021
"""
1122
>>> generate_all_combinations(n=4, k=2)
1223
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
24+
>>> generate_all_combinations(n=0, k=0)
25+
[[]]
26+
>>> generate_all_combinations(n=10, k=-1)
27+
Traceback (most recent call last):
28+
...
29+
RecursionError: maximum recursion depth exceeded
30+
>>> generate_all_combinations(n=-1, k=10)
31+
[]
32+
>>> generate_all_combinations(n=5, k=4)
33+
[[1, 2, 3, 4], [1, 2, 3, 5], [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]]
34+
>>> from itertools import combinations
35+
>>> all(generate_all_combinations(n, k) == combination_lists(n, k)
36+
... for n in range(1, 6) for k in range(1, 6))
37+
True
1338
"""
1439

1540
result: list[list[int]] = []
@@ -34,13 +59,17 @@ def create_all_state(
3459
current_list.pop()
3560

3661

37-
def print_all_state(total_list: list[list[int]]) -> None:
38-
for i in total_list:
39-
print(*i)
62+
if __name__ == "__main__":
63+
from doctest import testmod
4064

65+
testmod()
66+
print(generate_all_combinations(n=4, k=2))
67+
tests = ((n, k) for n in range(1, 5) for k in range(1, 5))
68+
for n, k in tests:
69+
print(n, k, generate_all_combinations(n, k) == combination_lists(n, k))
4170

42-
if __name__ == "__main__":
43-
n = 4
44-
k = 2
45-
total_list = generate_all_combinations(n, k)
46-
print_all_state(total_list)
71+
print("Benchmark:")
72+
from timeit import timeit
73+
74+
for func in ("combination_lists", "generate_all_combinations"):
75+
print(f"{func:>25}(): {timeit(f'{func}(n=4, k = 2)', globals=globals())}")

backtracking/minimax.py

+25-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ def minimax(
1616
depth: int, node_index: int, is_max: bool, scores: list[int], height: float
1717
) -> int:
1818
"""
19+
This function implements the minimax algorithm, which helps achieve the optimal
20+
score for a player in a two-player game by checking all possible moves.
21+
If the player is the maximizer, then the score is maximized.
22+
If the player is the minimizer, then the score is minimized.
23+
24+
Parameters:
25+
- depth: Current depth in the game tree.
26+
- node_index: Index of the current node in the scores list.
27+
- is_max: A boolean indicating whether the current move
28+
is for the maximizer (True) or minimizer (False).
29+
- scores: A list containing the scores of the leaves of the game tree.
30+
- height: The maximum height of the game tree.
31+
32+
Returns:
33+
- An integer representing the optimal score for the current player.
34+
1935
>>> import math
2036
>>> scores = [90, 23, 6, 33, 21, 65, 123, 34423]
2137
>>> height = math.log(len(scores), 2)
@@ -37,28 +53,36 @@ def minimax(
3753

3854
if depth < 0:
3955
raise ValueError("Depth cannot be less than 0")
40-
4156
if len(scores) == 0:
4257
raise ValueError("Scores cannot be empty")
4358

59+
# Base case: If the current depth equals the height of the tree,
60+
# return the score of the current node.
4461
if depth == height:
4562
return scores[node_index]
4663

64+
# If it's the maximizer's turn, choose the maximum score
65+
# between the two possible moves.
4766
if is_max:
4867
return max(
4968
minimax(depth + 1, node_index * 2, False, scores, height),
5069
minimax(depth + 1, node_index * 2 + 1, False, scores, height),
5170
)
5271

72+
# If it's the minimizer's turn, choose the minimum score
73+
# between the two possible moves.
5374
return min(
5475
minimax(depth + 1, node_index * 2, True, scores, height),
5576
minimax(depth + 1, node_index * 2 + 1, True, scores, height),
5677
)
5778

5879

5980
def main() -> None:
81+
# Sample scores and height calculation
6082
scores = [90, 23, 6, 33, 21, 65, 123, 34423]
6183
height = math.log(len(scores), 2)
84+
85+
# Calculate and print the optimal value using the minimax algorithm
6286
print("Optimal value : ", end="")
6387
print(minimax(0, 0, True, scores, height))
6488

0 commit comments

Comments
 (0)