Skip to content

Commit ec738b0

Browse files
authored
Merge pull request #1 from TheAlgorithms/master
sync fork
2 parents f680806 + 7df393f commit ec738b0

22 files changed

+205
-47
lines changed

bit_manipulation/binary_shifts.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Information on binary shifts:
2+
# https://docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types
3+
# https://www.interviewcake.com/concept/java/bit-shift
4+
5+
6+
def logical_left_shift(number: int, shift_amount: int) -> str:
7+
"""
8+
Take in 2 positive integers.
9+
'number' is the integer to be logically left shifted 'shift_amount' times.
10+
i.e. (number << shift_amount)
11+
Return the shifted binary representation.
12+
13+
>>> logical_left_shift(0, 1)
14+
'0b00'
15+
>>> logical_left_shift(1, 1)
16+
'0b10'
17+
>>> logical_left_shift(1, 5)
18+
'0b100000'
19+
>>> logical_left_shift(17, 2)
20+
'0b1000100'
21+
>>> logical_left_shift(1983, 4)
22+
'0b111101111110000'
23+
>>> logical_left_shift(1, -1)
24+
Traceback (most recent call last):
25+
...
26+
ValueError: both inputs must be positive integers
27+
"""
28+
if number < 0 or shift_amount < 0:
29+
raise ValueError("both inputs must be positive integers")
30+
31+
binary_number = str(bin(number))
32+
binary_number += "0" * shift_amount
33+
return binary_number
34+
35+
36+
def logical_right_shift(number: int, shift_amount: int) -> str:
37+
"""
38+
Take in positive 2 integers.
39+
'number' is the integer to be logically right shifted 'shift_amount' times.
40+
i.e. (number >>> shift_amount)
41+
Return the shifted binary representation.
42+
43+
>>> logical_right_shift(0, 1)
44+
'0b0'
45+
>>> logical_right_shift(1, 1)
46+
'0b0'
47+
>>> logical_right_shift(1, 5)
48+
'0b0'
49+
>>> logical_right_shift(17, 2)
50+
'0b100'
51+
>>> logical_right_shift(1983, 4)
52+
'0b1111011'
53+
>>> logical_right_shift(1, -1)
54+
Traceback (most recent call last):
55+
...
56+
ValueError: both inputs must be positive integers
57+
"""
58+
if number < 0 or shift_amount < 0:
59+
raise ValueError("both inputs must be positive integers")
60+
61+
binary_number = str(bin(number))[2:]
62+
if shift_amount >= len(binary_number):
63+
return "0b0"
64+
shifted_binary_number = binary_number[: len(binary_number) - shift_amount]
65+
return "0b" + shifted_binary_number
66+
67+
68+
def arithmetic_right_shift(number: int, shift_amount: int) -> str:
69+
"""
70+
Take in 2 integers.
71+
'number' is the integer to be arithmetically right shifted 'shift_amount' times.
72+
i.e. (number >> shift_amount)
73+
Return the shifted binary representation.
74+
75+
>>> arithmetic_right_shift(0, 1)
76+
'0b00'
77+
>>> arithmetic_right_shift(1, 1)
78+
'0b00'
79+
>>> arithmetic_right_shift(-1, 1)
80+
'0b11'
81+
>>> arithmetic_right_shift(17, 2)
82+
'0b000100'
83+
>>> arithmetic_right_shift(-17, 2)
84+
'0b111011'
85+
>>> arithmetic_right_shift(-1983, 4)
86+
'0b111110000100'
87+
"""
88+
if number >= 0: # Get binary representation of positive number
89+
binary_number = "0" + str(bin(number)).strip("-")[2:]
90+
else: # Get binary (2's complement) representation of negative number
91+
binary_number_length = len(bin(number)[3:]) # Find 2's complement of number
92+
binary_number = bin(abs(number) - (1 << binary_number_length))[3:]
93+
binary_number = (
94+
("1" + "0" * (binary_number_length - len(binary_number)) + binary_number)
95+
if number < 0
96+
else "0"
97+
)
98+
99+
if shift_amount >= len(binary_number):
100+
return "0b" + binary_number[0] * len(binary_number)
101+
return (
102+
"0b"
103+
+ binary_number[0] * shift_amount
104+
+ binary_number[: len(binary_number) - shift_amount]
105+
)
106+
107+
108+
if __name__ == "__main__":
109+
import doctest
110+
111+
doctest.testmod()
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Information on 2's complement: https://en.wikipedia.org/wiki/Two%27s_complement
2+
3+
4+
def twos_complement(number: int) -> str:
5+
"""
6+
Take in a negative integer 'number'.
7+
Return the two's complement representation of 'number'.
8+
9+
>>> twos_complement(0)
10+
'0b0'
11+
>>> twos_complement(-1)
12+
'0b11'
13+
>>> twos_complement(-5)
14+
'0b1011'
15+
>>> twos_complement(-17)
16+
'0b101111'
17+
>>> twos_complement(-207)
18+
'0b100110001'
19+
>>> twos_complement(1)
20+
Traceback (most recent call last):
21+
...
22+
ValueError: input must be a negative integer
23+
"""
24+
if number > 0:
25+
raise ValueError("input must be a negative integer")
26+
binary_number_length = len(bin(number)[3:])
27+
twos_complement_number = bin(abs(number) - (1 << binary_number_length))[3:]
28+
twos_complement_number = (
29+
(
30+
"1"
31+
+ "0" * (binary_number_length - len(twos_complement_number))
32+
+ twos_complement_number
33+
)
34+
if number < 0
35+
else "0"
36+
)
37+
return "0b" + twos_complement_number
38+
39+
40+
if __name__ == "__main__":
41+
import doctest
42+
43+
doctest.testmod()

ciphers/rsa_cipher.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def encryptAndWriteToFile(
118118
for i in range(len(encryptedBlocks)):
119119
encryptedBlocks[i] = str(encryptedBlocks[i])
120120
encryptedContent = ",".join(encryptedBlocks)
121-
encryptedContent = "{}_{}_{}".format(len(message), blockSize, encryptedContent)
121+
encryptedContent = f"{len(message)}_{blockSize}_{encryptedContent}"
122122
with open(messageFilename, "w") as fo:
123123
fo.write(encryptedContent)
124124
return encryptedContent

ciphers/rsa_key_generator.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ def makeKeyFiles(name: int, keySize: int) -> None:
4949
publicKey, privateKey = generateKey(keySize)
5050
print("\nWriting public key to file %s_pubkey.txt..." % name)
5151
with open("%s_pubkey.txt" % name, "w") as out_file:
52-
out_file.write("{},{},{}".format(keySize, publicKey[0], publicKey[1]))
52+
out_file.write(f"{keySize},{publicKey[0]},{publicKey[1]}")
5353

5454
print("Writing private key to file %s_privkey.txt..." % name)
5555
with open("%s_privkey.txt" % name, "w") as out_file:
56-
out_file.write("{},{},{}".format(keySize, privateKey[0], privateKey[1]))
56+
out_file.write(f"{keySize},{privateKey[0]},{privateKey[1]}")
5757

5858

5959
if __name__ == "__main__":

compression/burrows_wheeler.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,12 @@ def reverse_bwt(bwt_string: str, idx_original_string: int) -> str:
157157
entry_msg = "Provide a string that I will generate its BWT transform: "
158158
s = input(entry_msg).strip()
159159
result = bwt_transform(s)
160-
bwt_output_msg = "Burrows Wheeler transform for string '{}' results in '{}'"
161-
print(bwt_output_msg.format(s, result["bwt_string"]))
160+
print(
161+
f"Burrows Wheeler transform for string '{s}' results "
162+
f"in '{result['bwt_string']}'"
163+
)
162164
original_string = reverse_bwt(result["bwt_string"], result["idx_original_string"])
163-
fmt = (
164-
"Reversing Burrows Wheeler transform for entry '{}' we get original"
165-
" string '{}'"
165+
print(
166+
f"Reversing Burrows Wheeler transform for entry '{result['bwt_string']}' "
167+
f"we get original string '{original_string}'"
166168
)
167-
print(fmt.format(result["bwt_string"], original_string))

data_structures/binary_tree/non_recursive_segment_tree.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def __init__(self, arr: list[T], fnc: Callable[[T, T], T]) -> None:
4949
:param arr: list of elements for the segment tree
5050
:param fnc: commutative function for combine two elements
5151
52-
>>> SegmentTree(['a', 'b', 'c'], lambda a, b: '{}{}'.format(a, b)).query(0, 2)
52+
>>> SegmentTree(['a', 'b', 'c'], lambda a, b: f'{a}{b}').query(0, 2)
5353
'abc'
5454
>>> SegmentTree([(1, 2), (2, 3), (3, 4)],
5555
... lambda a, b: (a[0] + b[0], a[1] + b[1])).query(0, 2)

data_structures/binary_tree/red_black_tree.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -475,11 +475,13 @@ def __repr__(self) -> str:
475475
from pprint import pformat
476476

477477
if self.left is None and self.right is None:
478-
return "'{} {}'".format(self.label, (self.color and "red") or "blk")
478+
return f"'{self.label} {(self.color and 'red') or 'blk'}'"
479479
return pformat(
480480
{
481-
"%s %s"
482-
% (self.label, (self.color and "red") or "blk"): (self.left, self.right)
481+
f"{self.label} {(self.color and 'red') or 'blk'}": (
482+
self.left,
483+
self.right,
484+
)
483485
},
484486
indent=1,
485487
)

data_structures/linked_list/deque_doubly.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ def __init__(self, link_p, element, link_n):
2020
self._next = link_n
2121

2222
def has_next_and_prev(self):
23-
return " Prev -> {}, Next -> {}".format(
24-
self._prev is not None, self._next is not None
23+
return (
24+
f" Prev -> {self._prev is not None}, Next -> {self._next is not None}"
2525
)
2626

2727
def __init__(self):

dynamic_programming/climbing_stairs.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ def climb_stairs(n: int) -> int:
2525
...
2626
AssertionError: n needs to be positive integer, your input -7
2727
"""
28-
fmt = "n needs to be positive integer, your input {}"
29-
assert isinstance(n, int) and n > 0, fmt.format(n)
28+
assert (
29+
isinstance(n, int) and n > 0
30+
), f"n needs to be positive integer, your input {n}"
3031
if n == 1:
3132
return 1
3233
dp = [0] * (n + 1)

dynamic_programming/iterating_through_submasks.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ def list_of_submasks(mask: int) -> list[int]:
3737
3838
"""
3939

40-
fmt = "mask needs to be positive integer, your input {}"
41-
assert isinstance(mask, int) and mask > 0, fmt.format(mask)
40+
assert (
41+
isinstance(mask, int) and mask > 0
42+
), f"mask needs to be positive integer, your input {mask}"
4243

4344
"""
4445
first submask iterated will be mask itself then operation will be performed

graphics/bezier_curve.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# https://www.tutorialspoint.com/computer_graphics/computer_graphics_curves.htm
33
from __future__ import annotations
44

5-
from scipy.special import comb
5+
from scipy.special import comb # type: ignore
66

77

88
class BezierCurve:
@@ -78,7 +78,7 @@ def plot_curve(self, step_size: float = 0.01):
7878
step_size: defines the step(s) at which to evaluate the Bezier curve.
7979
The smaller the step size, the finer the curve produced.
8080
"""
81-
from matplotlib import pyplot as plt
81+
from matplotlib import pyplot as plt # type: ignore
8282

8383
to_plot_x: list[float] = [] # x coordinates of points to plot
8484
to_plot_y: list[float] = [] # y coordinates of points to plot

machine_learning/knn_sklearn.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@
2626
prediction = knn.predict(X_new)
2727

2828
print(
29-
"\nNew array: \n {}"
30-
"\n\nTarget Names Prediction: \n {}".format(X_new, iris["target_names"][prediction])
29+
f"\nNew array: \n {X_new}\n\nTarget Names Prediction: \n"
30+
f" {iris['target_names'][prediction]}"
3131
)

maths/3n_plus_1.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def n31(a: int) -> tuple[list[int], int]:
99
"""
1010

1111
if not isinstance(a, int):
12-
raise TypeError("Must be int, not {}".format(type(a).__name__))
12+
raise TypeError(f"Must be int, not {type(a).__name__}")
1313
if a < 1:
1414
raise ValueError(f"Given integer must be greater than 1, not {a}")
1515

maths/quadratic_equations_complex_numbers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ def quadratic_roots(a: int, b: int, c: int) -> tuple[complex, complex]:
3030

3131

3232
def main():
33-
solutions = quadratic_roots(a=5, b=6, c=1)
34-
print("The solutions are: {} and {}".format(*solutions))
33+
solution1, solution2 = quadratic_roots(a=5, b=6, c=1)
34+
print(f"The solutions are: {solution1} and {solution2}")
3535

3636

3737
if __name__ == "__main__":

matrix/nth_fibonacci_using_matrix_exponentiation.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ def nth_fibonacci_bruteforce(n):
7171

7272

7373
def main():
74-
fmt = (
75-
"{} fibonacci number using matrix exponentiation is {} and using bruteforce "
76-
"is {}\n"
77-
)
7874
for ordinal in "0th 1st 2nd 3rd 10th 100th 1000th".split():
7975
n = int("".join(c for c in ordinal if c in "0123456789")) # 1000th --> 1000
80-
print(fmt.format(ordinal, nth_fibonacci_matrix(n), nth_fibonacci_bruteforce(n)))
76+
print(
77+
f"{ordinal} fibonacci number using matrix exponentiation is "
78+
f"{nth_fibonacci_matrix(n)} and using bruteforce is "
79+
f"{nth_fibonacci_bruteforce(n)}\n"
80+
)
8181
# from timeit import timeit
8282
# print(timeit("nth_fibonacci_matrix(1000000)",
8383
# "from main import nth_fibonacci_matrix", number=5))

matrix/sherman_morrison.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ def __mul__(self, another):
175175
result[r, c] += self[r, i] * another[i, c]
176176
return result
177177
else:
178-
raise TypeError(
179-
"Unsupported type given for another ({})".format(type(another))
180-
)
178+
raise TypeError(f"Unsupported type given for another ({type(another)})")
181179

182180
def transpose(self):
183181
"""
@@ -260,7 +258,7 @@ def test1():
260258
print(f"v is {v}")
261259
print("uv^T is %s" % (u * v.transpose()))
262260
# Sherman Morrison
263-
print("(a + uv^T)^(-1) is {}".format(ainv.ShermanMorrison(u, v)))
261+
print(f"(a + uv^T)^(-1) is {ainv.ShermanMorrison(u, v)}")
264262

265263
def test2():
266264
import doctest

sorts/bucket_sort.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
2828
Source: https://en.wikipedia.org/wiki/Bucket_sort
2929
"""
30+
from typing import List
3031

3132

3233
def bucket_sort(my_list: list) -> list:
@@ -51,7 +52,7 @@ def bucket_sort(my_list: list) -> list:
5152
return []
5253
min_value, max_value = min(my_list), max(my_list)
5354
bucket_count = int(max_value - min_value) + 1
54-
buckets = [[] for _ in range(bucket_count)]
55+
buckets: List[list] = [[] for _ in range(bucket_count)]
5556

5657
for i in range(len(my_list)):
5758
buckets[(int(my_list[i] - min_value) // bucket_count)].append(my_list[i])

sorts/cocktail_shaker_sort.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ def cocktail_shaker_sort(unsorted: list) -> list:
3333
swapped = True
3434

3535
if not swapped:
36-
return unsorted
36+
break
37+
return unsorted
3738

3839

3940
if __name__ == "__main__":

sorts/patience_sort.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from bisect import bisect_left
22
from functools import total_ordering
33
from heapq import merge
4+
from typing import List
45

56
"""
67
A pure Python implementation of the patience sort algorithm
@@ -43,7 +44,7 @@ def patience_sort(collection: list) -> list:
4344
>>> patience_sort([-3, -17, -48])
4445
[-48, -17, -3]
4546
"""
46-
stacks = []
47+
stacks: List[Stack] = []
4748
# sort into stacks
4849
for element in collection:
4950
new_stacks = Stack([element])

sorts/radix_sort.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def radix_sort(list_of_ints: List[int]) -> List[int]:
3030
max_digit = max(list_of_ints)
3131
while placement <= max_digit:
3232
# declare and initialize empty buckets
33-
buckets = [list() for _ in range(RADIX)]
33+
buckets: List[list] = [list() for _ in range(RADIX)]
3434
# split list_of_ints between the buckets
3535
for i in list_of_ints:
3636
tmp = int((i / placement) % RADIX)

0 commit comments

Comments
 (0)