Skip to content

Commit e60735b

Browse files
authored
Merge branch 'master' into branch2
2 parents f82580d + 63180d7 commit e60735b

Some content is hidden

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

54 files changed

+978
-239
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
with:
1515
enable-cache: true
1616
cache-dependency-glob: uv.lock
17-
- uses: actions/setup-python@v5
17+
- uses: actions/setup-python@v6
1818
with:
1919
python-version: 3.x
2020
allow-prereleases: true

.github/workflows/directory_writer.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
- uses: actions/checkout@v5
1010
with:
1111
fetch-depth: 0
12-
- uses: actions/setup-python@v5
12+
- uses: actions/setup-python@v6
1313
with:
1414
python-version: 3.x
1515
- name: Write DIRECTORY.md

.github/workflows/project_euler.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
steps:
1717
- uses: actions/checkout@v5
1818
- uses: astral-sh/setup-uv@v6
19-
- uses: actions/setup-python@v5
19+
- uses: actions/setup-python@v6
2020
with:
2121
python-version: 3.x
2222
- run: uv sync --group=euler-validate --group=test
@@ -26,7 +26,7 @@ jobs:
2626
steps:
2727
- uses: actions/checkout@v5
2828
- uses: astral-sh/setup-uv@v6
29-
- uses: actions/setup-python@v5
29+
- uses: actions/setup-python@v6
3030
with:
3131
python-version: 3.x
3232
- run: uv sync --group=euler-validate --group=test

.github/workflows/sphinx.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ jobs:
2727
steps:
2828
- uses: actions/checkout@v5
2929
- uses: astral-sh/setup-uv@v6
30-
- uses: actions/setup-python@v5
30+
- uses: actions/setup-python@v6
3131
with:
3232
python-version: 3.13
3333
allow-prereleases: true
3434
- run: uv sync --group=docs
3535
- uses: actions/configure-pages@v5
3636
- run: uv run sphinx-build -c docs . docs/_build/html
37-
- uses: actions/upload-pages-artifact@v3
37+
- uses: actions/upload-pages-artifact@v4
3838
with:
3939
path: docs/_build/html
4040

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ repos:
1616
- id: auto-walrus
1717

1818
- repo: https://github.com/astral-sh/ruff-pre-commit
19-
rev: v0.12.9
19+
rev: v0.13.0
2020
hooks:
2121
- id: ruff-check
2222
- id: ruff-format
@@ -47,7 +47,7 @@ repos:
4747
- id: validate-pyproject
4848

4949
- repo: https://github.com/pre-commit/mirrors-mypy
50-
rev: v1.15.0
50+
rev: v1.17.1
5151
hooks:
5252
- id: mypy
5353
args:

DIRECTORY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* [Combination Sum](backtracking/combination_sum.py)
1313
* [Crossword Puzzle Solver](backtracking/crossword_puzzle_solver.py)
1414
* [Generate Parentheses](backtracking/generate_parentheses.py)
15+
* [Generate Parentheses Iterative](backtracking/generate_parentheses_iterative.py)
1516
* [Hamiltonian Cycle](backtracking/hamiltonian_cycle.py)
1617
* [Knight Tour](backtracking/knight_tour.py)
1718
* [Match Word Pattern](backtracking/match_word_pattern.py)
@@ -175,6 +176,7 @@
175176

176177
## Data Compression
177178
* [Burrows Wheeler](data_compression/burrows_wheeler.py)
179+
* [Coordinate Compression](data_compression/coordinate_compression.py)
178180
* [Huffman](data_compression/huffman.py)
179181
* [Lempel Ziv](data_compression/lempel_ziv.py)
180182
* [Lempel Ziv Decompress](data_compression/lempel_ziv_decompress.py)
@@ -724,6 +726,7 @@
724726
* [Secant Method](maths/numerical_analysis/secant_method.py)
725727
* [Simpson Rule](maths/numerical_analysis/simpson_rule.py)
726728
* [Square Root](maths/numerical_analysis/square_root.py)
729+
* [Weierstrass Method](maths/numerical_analysis/weierstrass_method.py)
727730
* [Odd Sieve](maths/odd_sieve.py)
728731
* [Perfect Cube](maths/perfect_cube.py)
729732
* [Perfect Number](maths/perfect_number.py)
@@ -957,6 +960,7 @@
957960
* [Sol1](project_euler/problem_009/sol1.py)
958961
* [Sol2](project_euler/problem_009/sol2.py)
959962
* [Sol3](project_euler/problem_009/sol3.py)
963+
* [Sol4](project_euler/problem_009/sol4.py)
960964
* Problem 010
961965
* [Sol1](project_euler/problem_010/sol1.py)
962966
* [Sol2](project_euler/problem_010/sol2.py)
@@ -1267,6 +1271,7 @@
12671271
* [Comb Sort](sorts/comb_sort.py)
12681272
* [Counting Sort](sorts/counting_sort.py)
12691273
* [Cycle Sort](sorts/cycle_sort.py)
1274+
* [Cyclic Sort](sorts/cyclic_sort.py)
12701275
* [Double Sort](sorts/double_sort.py)
12711276
* [Dutch National Flag Sort](sorts/dutch_national_flag_sort.py)
12721277
* [Exchange Sort](sorts/exchange_sort.py)
@@ -1297,6 +1302,7 @@
12971302
* [Shell Sort](sorts/shell_sort.py)
12981303
* [Shrink Shell Sort](sorts/shrink_shell_sort.py)
12991304
* [Slowsort](sorts/slowsort.py)
1305+
* [Stalin Sort](sorts/stalin_sort.py)
13001306
* [Stooge Sort](sorts/stooge_sort.py)
13011307
* [Strand Sort](sorts/strand_sort.py)
13021308
* [Tim Sort](sorts/tim_sort.py)

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<img src="https://raw.githubusercontent.com/TheAlgorithms/website/1cd824df116b27029f17c2d1b42d81731f28a920/public/logo.svg" height="100">
55
</a>
66
<h1><a href="https://github.com/TheAlgorithms/">The Algorithms</a> - Python</h1>
7+
78
<!-- Labels: -->
89
<!-- First row: -->
910
<a href="https://gitpod.io/#https://github.com/TheAlgorithms/Python">
@@ -19,6 +20,7 @@
1920
<a href="https://gitter.im/TheAlgorithms/community">
2021
<img src="https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square" height="20" alt="Gitter chat">
2122
</a>
23+
2224
<!-- Second row: -->
2325
<br>
2426
<a href="https://github.com/TheAlgorithms/Python/actions">
@@ -27,23 +29,24 @@
2729
<a href="https://github.com/pre-commit/pre-commit">
2830
<img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" height="20" alt="pre-commit">
2931
</a>
30-
<a href="https://github.com/psf/black">
31-
<img src="https://img.shields.io/static/v1?label=code%20style&message=black&color=black&style=flat-square" height="20" alt="code style: black">
32+
<a href="https://docs.astral.sh/ruff/formatter/">
33+
<img src="https://img.shields.io/static/v1?label=code%20style&message=ruff&color=black&style=flat-square" height="20" alt="code style: black">
3234
</a>
35+
3336
<!-- Short description: -->
34-
<h3>All algorithms implemented in Python - for education</h3>
37+
<h3>All algorithms implemented in Python - for education 📚</h3>
3538
</div>
3639

3740
Implementations are for learning purposes only. They may be less efficient than the implementations in the Python standard library. Use them at your discretion.
3841

39-
## Getting Started
42+
## 🚀 Getting Started
4043

41-
Read through our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
44+
📋 Read through our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
4245

43-
## Community Channels
46+
## 🌐 Community Channels
4447

4548
We are on [Discord](https://the-algorithms.com/discord) and [Gitter](https://gitter.im/TheAlgorithms/community)! Community channels are a great way for you to ask questions and get help. Please join us!
4649

47-
## List of Algorithms
50+
## 📜 List of Algorithms
4851

4952
See our [directory](DIRECTORY.md) for easier navigation and a better overview of the project.

backtracking/combination_sum.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,18 @@ def combination_sum(candidates: list, target: int) -> list:
4747
>>> combination_sum([-8, 2.3, 0], 1)
4848
Traceback (most recent call last):
4949
...
50-
RecursionError: maximum recursion depth exceeded
50+
ValueError: All elements in candidates must be non-negative
51+
>>> combination_sum([], 1)
52+
Traceback (most recent call last):
53+
...
54+
ValueError: Candidates list should not be empty
5155
"""
56+
if not candidates:
57+
raise ValueError("Candidates list should not be empty")
58+
59+
if any(x < 0 for x in candidates):
60+
raise ValueError("All elements in candidates must be non-negative")
61+
5262
path = [] # type: list[int]
5363
answer = [] # type: list[int]
5464
backtrack(candidates, path, answer, target, 0)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
def generate_parentheses_iterative(length: int) -> list:
2+
"""
3+
Generate all valid combinations of parentheses (Iterative Approach).
4+
5+
The algorithm works as follows:
6+
1. Initialize an empty list to store the combinations.
7+
2. Initialize a stack to keep track of partial combinations.
8+
3. Start with empty string and push it onstack along with the counts of '(' and ')'.
9+
4. While the stack is not empty:
10+
a. Pop a partial combination and its open and close counts from the stack.
11+
b. If the combination length is equal to 2*length, add it to the result.
12+
c. If open count < length, push new combination with added '(' on stack.
13+
d. If close count < open count, push new combination with added ')' on stack.
14+
5. Return the result containing all valid combinations.
15+
16+
Args:
17+
length: The desired length of the parentheses combinations
18+
19+
Returns:
20+
A list of strings representing valid combinations of parentheses
21+
22+
Time Complexity:
23+
O(2^(2*length))
24+
25+
Space Complexity:
26+
O(2^(2*length))
27+
28+
>>> generate_parentheses_iterative(3)
29+
['()()()', '()(())', '(())()', '(()())', '((()))']
30+
>>> generate_parentheses_iterative(2)
31+
['()()', '(())']
32+
>>> generate_parentheses_iterative(1)
33+
['()']
34+
>>> generate_parentheses_iterative(0)
35+
['']
36+
"""
37+
result = []
38+
stack = []
39+
40+
# Each element in stack is a tuple (current_combination, open_count, close_count)
41+
stack.append(("", 0, 0))
42+
43+
while stack:
44+
current_combination, open_count, close_count = stack.pop()
45+
46+
if len(current_combination) == 2 * length:
47+
result.append(current_combination)
48+
49+
if open_count < length:
50+
stack.append((current_combination + "(", open_count + 1, close_count))
51+
52+
if close_count < open_count:
53+
stack.append((current_combination + ")", open_count, close_count + 1))
54+
55+
return result
56+
57+
58+
if __name__ == "__main__":
59+
import doctest
60+
61+
doctest.testmod()
62+
print(generate_parentheses_iterative(3))

bit_manipulation/reverse_bits.py

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,83 @@
11
def get_reverse_bit_string(number: int) -> str:
22
"""
3-
return the bit string of an integer
3+
Return the reverse bit string of a 32 bit integer
44
55
>>> get_reverse_bit_string(9)
66
'10010000000000000000000000000000'
77
>>> get_reverse_bit_string(43)
88
'11010100000000000000000000000000'
99
>>> get_reverse_bit_string(2873)
1010
'10011100110100000000000000000000'
11+
>>> get_reverse_bit_string(2550136832)
12+
'00000000000000000000000000011001'
1113
>>> get_reverse_bit_string("this is not a number")
1214
Traceback (most recent call last):
1315
...
14-
TypeError: operation can not be conducted on a object of type str
16+
TypeError: operation can not be conducted on an object of type str
1517
"""
1618
if not isinstance(number, int):
1719
msg = (
18-
"operation can not be conducted on a object of type "
20+
"operation can not be conducted on an object of type "
1921
f"{type(number).__name__}"
2022
)
2123
raise TypeError(msg)
2224
bit_string = ""
2325
for _ in range(32):
2426
bit_string += str(number % 2)
25-
number = number >> 1
27+
number >>= 1
2628
return bit_string
2729

2830

29-
def reverse_bit(number: int) -> str:
31+
def reverse_bit(number: int) -> int:
3032
"""
31-
Take in an 32 bit integer, reverse its bits,
32-
return a string of reverse bits
33-
34-
result of a reverse_bit and operation on the integer provided.
33+
Take in a 32 bit integer, reverse its bits, return a 32 bit integer result
3534
3635
>>> reverse_bit(25)
37-
'00000000000000000000000000011001'
36+
2550136832
3837
>>> reverse_bit(37)
39-
'00000000000000000000000000100101'
38+
2751463424
4039
>>> reverse_bit(21)
41-
'00000000000000000000000000010101'
40+
2818572288
4241
>>> reverse_bit(58)
43-
'00000000000000000000000000111010'
42+
1543503872
4443
>>> reverse_bit(0)
45-
'00000000000000000000000000000000'
44+
0
4645
>>> reverse_bit(256)
47-
'00000000000000000000000100000000'
46+
8388608
47+
>>> reverse_bit(2550136832)
48+
25
4849
>>> reverse_bit(-1)
4950
Traceback (most recent call last):
5051
...
51-
ValueError: the value of input must be positive
52+
ValueError: The value of input must be non-negative
5253
5354
>>> reverse_bit(1.1)
5455
Traceback (most recent call last):
5556
...
56-
TypeError: Input value must be a 'int' type
57+
TypeError: Input value must be an 'int' type
5758
5859
>>> reverse_bit("0")
5960
Traceback (most recent call last):
6061
...
61-
TypeError: '<' not supported between instances of 'str' and 'int'
62+
TypeError: Input value must be an 'int' type
6263
"""
64+
if not isinstance(number, int):
65+
raise TypeError("Input value must be an 'int' type")
6366
if number < 0:
64-
raise ValueError("the value of input must be positive")
65-
elif isinstance(number, float):
66-
raise TypeError("Input value must be a 'int' type")
67-
elif isinstance(number, str):
68-
raise TypeError("'<' not supported between instances of 'str' and 'int'")
67+
raise ValueError("The value of input must be non-negative")
68+
6969
result = 0
70-
# iterator over [1 to 32],since we are dealing with 32 bit integer
71-
for _ in range(1, 33):
70+
# iterator over [0 to 31], since we are dealing with a 32 bit integer
71+
for _ in range(32):
7272
# left shift the bits by unity
73-
result = result << 1
73+
result <<= 1
7474
# get the end bit
75-
end_bit = number % 2
75+
end_bit = number & 1
7676
# right shift the bits by unity
77-
number = number >> 1
78-
# add that bit to our ans
79-
result = result | end_bit
80-
return get_reverse_bit_string(result)
77+
number >>= 1
78+
# add that bit to our answer
79+
result |= end_bit
80+
return result
8181

8282

8383
if __name__ == "__main__":

0 commit comments

Comments
 (0)