mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-26 02:48:40 +00:00
Merge branch 'TheAlgorithms:master' into master
This commit is contained in:
commit
6e7ed74f98
@ -16,7 +16,7 @@ repos:
|
|||||||
- id: auto-walrus
|
- id: auto-walrus
|
||||||
|
|
||||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||||
rev: v0.0.263
|
rev: v0.0.267
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ repos:
|
|||||||
- tomli
|
- tomli
|
||||||
|
|
||||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||||
rev: "0.11.1"
|
rev: "0.11.2"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyproject-fmt
|
- id: pyproject-fmt
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ repos:
|
|||||||
- id: validate-pyproject
|
- id: validate-pyproject
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v1.2.0
|
rev: v1.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
args:
|
args:
|
||||||
|
@ -294,7 +294,6 @@
|
|||||||
* [Mergesort](divide_and_conquer/mergesort.py)
|
* [Mergesort](divide_and_conquer/mergesort.py)
|
||||||
* [Peak](divide_and_conquer/peak.py)
|
* [Peak](divide_and_conquer/peak.py)
|
||||||
* [Power](divide_and_conquer/power.py)
|
* [Power](divide_and_conquer/power.py)
|
||||||
* [Strassen Matrix Multiplication](divide_and_conquer/strassen_matrix_multiplication.py)
|
|
||||||
|
|
||||||
## Dynamic Programming
|
## Dynamic Programming
|
||||||
* [Abbreviation](dynamic_programming/abbreviation.py)
|
* [Abbreviation](dynamic_programming/abbreviation.py)
|
||||||
@ -632,6 +631,7 @@
|
|||||||
* [Radians](maths/radians.py)
|
* [Radians](maths/radians.py)
|
||||||
* [Radix2 Fft](maths/radix2_fft.py)
|
* [Radix2 Fft](maths/radix2_fft.py)
|
||||||
* [Relu](maths/relu.py)
|
* [Relu](maths/relu.py)
|
||||||
|
* [Remove Digit](maths/remove_digit.py)
|
||||||
* [Runge Kutta](maths/runge_kutta.py)
|
* [Runge Kutta](maths/runge_kutta.py)
|
||||||
* [Segmented Sieve](maths/segmented_sieve.py)
|
* [Segmented Sieve](maths/segmented_sieve.py)
|
||||||
* Series
|
* Series
|
||||||
@ -694,6 +694,8 @@
|
|||||||
|
|
||||||
## Neural Network
|
## Neural Network
|
||||||
* [2 Hidden Layers Neural Network](neural_network/2_hidden_layers_neural_network.py)
|
* [2 Hidden Layers Neural Network](neural_network/2_hidden_layers_neural_network.py)
|
||||||
|
* Activation Functions
|
||||||
|
* [Exponential Linear Unit](neural_network/activation_functions/exponential_linear_unit.py)
|
||||||
* [Back Propagation Neural Network](neural_network/back_propagation_neural_network.py)
|
* [Back Propagation Neural Network](neural_network/back_propagation_neural_network.py)
|
||||||
* [Convolution Neural Network](neural_network/convolution_neural_network.py)
|
* [Convolution Neural Network](neural_network/convolution_neural_network.py)
|
||||||
* [Input Data](neural_network/input_data.py)
|
* [Input Data](neural_network/input_data.py)
|
||||||
@ -1080,6 +1082,7 @@
|
|||||||
|
|
||||||
## Sorts
|
## Sorts
|
||||||
* [Bead Sort](sorts/bead_sort.py)
|
* [Bead Sort](sorts/bead_sort.py)
|
||||||
|
* [Binary Insertion Sort](sorts/binary_insertion_sort.py)
|
||||||
* [Bitonic Sort](sorts/bitonic_sort.py)
|
* [Bitonic Sort](sorts/bitonic_sort.py)
|
||||||
* [Bogo Sort](sorts/bogo_sort.py)
|
* [Bogo Sort](sorts/bogo_sort.py)
|
||||||
* [Bubble Sort](sorts/bubble_sort.py)
|
* [Bubble Sort](sorts/bubble_sort.py)
|
||||||
@ -1170,6 +1173,7 @@
|
|||||||
* [Reverse Words](strings/reverse_words.py)
|
* [Reverse Words](strings/reverse_words.py)
|
||||||
* [Snake Case To Camel Pascal Case](strings/snake_case_to_camel_pascal_case.py)
|
* [Snake Case To Camel Pascal Case](strings/snake_case_to_camel_pascal_case.py)
|
||||||
* [Split](strings/split.py)
|
* [Split](strings/split.py)
|
||||||
|
* [String Switch Case](strings/string_switch_case.py)
|
||||||
* [Text Justification](strings/text_justification.py)
|
* [Text Justification](strings/text_justification.py)
|
||||||
* [Top K Frequent Words](strings/top_k_frequent_words.py)
|
* [Top K Frequent Words](strings/top_k_frequent_words.py)
|
||||||
* [Upper](strings/upper.py)
|
* [Upper](strings/upper.py)
|
||||||
|
@ -96,7 +96,7 @@ def add_si_prefix(value: float) -> str:
|
|||||||
for name_prefix, value_prefix in prefixes.items():
|
for name_prefix, value_prefix in prefixes.items():
|
||||||
numerical_part = value / (10**value_prefix)
|
numerical_part = value / (10**value_prefix)
|
||||||
if numerical_part > 1:
|
if numerical_part > 1:
|
||||||
return f"{str(numerical_part)} {name_prefix}"
|
return f"{numerical_part!s} {name_prefix}"
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ def add_binary_prefix(value: float) -> str:
|
|||||||
for prefix in BinaryUnit:
|
for prefix in BinaryUnit:
|
||||||
numerical_part = value / (2**prefix.value)
|
numerical_part = value / (2**prefix.value)
|
||||||
if numerical_part > 1:
|
if numerical_part > 1:
|
||||||
return f"{str(numerical_part)} {prefix.name}"
|
return f"{numerical_part!s} {prefix.name}"
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,8 +121,8 @@ def rgb_to_hsv(red: int, green: int, blue: int) -> list[float]:
|
|||||||
float_red = red / 255
|
float_red = red / 255
|
||||||
float_green = green / 255
|
float_green = green / 255
|
||||||
float_blue = blue / 255
|
float_blue = blue / 255
|
||||||
value = max(max(float_red, float_green), float_blue)
|
value = max(float_red, float_green, float_blue)
|
||||||
chroma = value - min(min(float_red, float_green), float_blue)
|
chroma = value - min(float_red, float_green, float_blue)
|
||||||
saturation = 0 if value == 0 else chroma / value
|
saturation = 0 if value == 0 else chroma / value
|
||||||
|
|
||||||
if chroma == 0:
|
if chroma == 0:
|
||||||
|
@ -96,7 +96,7 @@ def test_nearest_neighbour(
|
|||||||
|
|
||||||
|
|
||||||
def test_local_binary_pattern():
|
def test_local_binary_pattern():
|
||||||
file_path: str = "digital_image_processing/image_data/lena.jpg"
|
file_path = "digital_image_processing/image_data/lena.jpg"
|
||||||
|
|
||||||
# Reading the image and converting it to grayscale.
|
# Reading the image and converting it to grayscale.
|
||||||
image = imread(file_path, 0)
|
image = imread(file_path, 0)
|
||||||
|
@ -122,7 +122,7 @@ def strassen(matrix1: list, matrix2: list) -> list:
|
|||||||
if dimension1[0] == dimension1[1] and dimension2[0] == dimension2[1]:
|
if dimension1[0] == dimension1[1] and dimension2[0] == dimension2[1]:
|
||||||
return [matrix1, matrix2]
|
return [matrix1, matrix2]
|
||||||
|
|
||||||
maximum = max(max(dimension1), max(dimension2))
|
maximum = max(dimension1, dimension2)
|
||||||
maxim = int(math.pow(2, math.ceil(math.log2(maximum))))
|
maxim = int(math.pow(2, math.ceil(math.log2(maximum))))
|
||||||
new_matrix1 = matrix1
|
new_matrix1 = matrix1
|
||||||
new_matrix2 = matrix2
|
new_matrix2 = matrix2
|
@ -24,7 +24,7 @@ class Fibonacci:
|
|||||||
return self.sequence[:index]
|
return self.sequence[:index]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
print(
|
print(
|
||||||
"Fibonacci Series Using Dynamic Programming\n",
|
"Fibonacci Series Using Dynamic Programming\n",
|
||||||
"Enter the index of the Fibonacci number you want to calculate ",
|
"Enter the index of the Fibonacci number you want to calculate ",
|
||||||
|
@ -21,6 +21,54 @@ MUTATION_PROBABILITY = 0.4
|
|||||||
random.seed(random.randint(0, 1000))
|
random.seed(random.randint(0, 1000))
|
||||||
|
|
||||||
|
|
||||||
|
def evaluate(item: str, main_target: str) -> tuple[str, float]:
|
||||||
|
"""
|
||||||
|
Evaluate how similar the item is with the target by just
|
||||||
|
counting each char in the right position
|
||||||
|
>>> evaluate("Helxo Worlx", "Hello World")
|
||||||
|
('Helxo Worlx', 9.0)
|
||||||
|
"""
|
||||||
|
score = len([g for position, g in enumerate(item) if g == main_target[position]])
|
||||||
|
return (item, float(score))
|
||||||
|
|
||||||
|
|
||||||
|
def crossover(parent_1: str, parent_2: str) -> tuple[str, str]:
|
||||||
|
"""Slice and combine two string at a random point."""
|
||||||
|
random_slice = random.randint(0, len(parent_1) - 1)
|
||||||
|
child_1 = parent_1[:random_slice] + parent_2[random_slice:]
|
||||||
|
child_2 = parent_2[:random_slice] + parent_1[random_slice:]
|
||||||
|
return (child_1, child_2)
|
||||||
|
|
||||||
|
|
||||||
|
def mutate(child: str, genes: list[str]) -> str:
|
||||||
|
"""Mutate a random gene of a child with another one from the list."""
|
||||||
|
child_list = list(child)
|
||||||
|
if random.uniform(0, 1) < MUTATION_PROBABILITY:
|
||||||
|
child_list[random.randint(0, len(child)) - 1] = random.choice(genes)
|
||||||
|
return "".join(child_list)
|
||||||
|
|
||||||
|
|
||||||
|
# Select, crossover and mutate a new population.
|
||||||
|
def select(
|
||||||
|
parent_1: tuple[str, float],
|
||||||
|
population_score: list[tuple[str, float]],
|
||||||
|
genes: list[str],
|
||||||
|
) -> list[str]:
|
||||||
|
"""Select the second parent and generate new population"""
|
||||||
|
pop = []
|
||||||
|
# Generate more children proportionally to the fitness score.
|
||||||
|
child_n = int(parent_1[1] * 100) + 1
|
||||||
|
child_n = 10 if child_n >= 10 else child_n
|
||||||
|
for _ in range(child_n):
|
||||||
|
parent_2 = population_score[random.randint(0, N_SELECTED)][0]
|
||||||
|
|
||||||
|
child_1, child_2 = crossover(parent_1[0], parent_2)
|
||||||
|
# Append new string to the population list.
|
||||||
|
pop.append(mutate(child_1, genes))
|
||||||
|
pop.append(mutate(child_2, genes))
|
||||||
|
return pop
|
||||||
|
|
||||||
|
|
||||||
def basic(target: str, genes: list[str], debug: bool = True) -> tuple[int, int, str]:
|
def basic(target: str, genes: list[str], debug: bool = True) -> tuple[int, int, str]:
|
||||||
"""
|
"""
|
||||||
Verify that the target contains no genes besides the ones inside genes variable.
|
Verify that the target contains no genes besides the ones inside genes variable.
|
||||||
@ -70,17 +118,6 @@ def basic(target: str, genes: list[str], debug: bool = True) -> tuple[int, int,
|
|||||||
total_population += len(population)
|
total_population += len(population)
|
||||||
|
|
||||||
# Random population created. Now it's time to evaluate.
|
# Random population created. Now it's time to evaluate.
|
||||||
def evaluate(item: str, main_target: str = target) -> tuple[str, float]:
|
|
||||||
"""
|
|
||||||
Evaluate how similar the item is with the target by just
|
|
||||||
counting each char in the right position
|
|
||||||
>>> evaluate("Helxo Worlx", Hello World)
|
|
||||||
["Helxo Worlx", 9]
|
|
||||||
"""
|
|
||||||
score = len(
|
|
||||||
[g for position, g in enumerate(item) if g == main_target[position]]
|
|
||||||
)
|
|
||||||
return (item, float(score))
|
|
||||||
|
|
||||||
# Adding a bit of concurrency can make everything faster,
|
# Adding a bit of concurrency can make everything faster,
|
||||||
#
|
#
|
||||||
@ -94,7 +131,7 @@ def basic(target: str, genes: list[str], debug: bool = True) -> tuple[int, int,
|
|||||||
#
|
#
|
||||||
# but with a simple algorithm like this, it will probably be slower.
|
# but with a simple algorithm like this, it will probably be slower.
|
||||||
# We just need to call evaluate for every item inside the population.
|
# We just need to call evaluate for every item inside the population.
|
||||||
population_score = [evaluate(item) for item in population]
|
population_score = [evaluate(item, target) for item in population]
|
||||||
|
|
||||||
# Check if there is a matching evolution.
|
# Check if there is a matching evolution.
|
||||||
population_score = sorted(population_score, key=lambda x: x[1], reverse=True)
|
population_score = sorted(population_score, key=lambda x: x[1], reverse=True)
|
||||||
@ -121,41 +158,9 @@ def basic(target: str, genes: list[str], debug: bool = True) -> tuple[int, int,
|
|||||||
(item, score / len(target)) for item, score in population_score
|
(item, score / len(target)) for item, score in population_score
|
||||||
]
|
]
|
||||||
|
|
||||||
# Select, crossover and mutate a new population.
|
|
||||||
def select(parent_1: tuple[str, float]) -> list[str]:
|
|
||||||
"""Select the second parent and generate new population"""
|
|
||||||
pop = []
|
|
||||||
# Generate more children proportionally to the fitness score.
|
|
||||||
child_n = int(parent_1[1] * 100) + 1
|
|
||||||
child_n = 10 if child_n >= 10 else child_n
|
|
||||||
for _ in range(child_n):
|
|
||||||
parent_2 = population_score[ # noqa: B023
|
|
||||||
random.randint(0, N_SELECTED)
|
|
||||||
][0]
|
|
||||||
|
|
||||||
child_1, child_2 = crossover(parent_1[0], parent_2)
|
|
||||||
# Append new string to the population list.
|
|
||||||
pop.append(mutate(child_1))
|
|
||||||
pop.append(mutate(child_2))
|
|
||||||
return pop
|
|
||||||
|
|
||||||
def crossover(parent_1: str, parent_2: str) -> tuple[str, str]:
|
|
||||||
"""Slice and combine two string at a random point."""
|
|
||||||
random_slice = random.randint(0, len(parent_1) - 1)
|
|
||||||
child_1 = parent_1[:random_slice] + parent_2[random_slice:]
|
|
||||||
child_2 = parent_2[:random_slice] + parent_1[random_slice:]
|
|
||||||
return (child_1, child_2)
|
|
||||||
|
|
||||||
def mutate(child: str) -> str:
|
|
||||||
"""Mutate a random gene of a child with another one from the list."""
|
|
||||||
child_list = list(child)
|
|
||||||
if random.uniform(0, 1) < MUTATION_PROBABILITY:
|
|
||||||
child_list[random.randint(0, len(child)) - 1] = random.choice(genes)
|
|
||||||
return "".join(child_list)
|
|
||||||
|
|
||||||
# This is selection
|
# This is selection
|
||||||
for i in range(N_SELECTED):
|
for i in range(N_SELECTED):
|
||||||
population.extend(select(population_score[int(i)]))
|
population.extend(select(population_score[int(i)], population_score, genes))
|
||||||
# Check if the population has already reached the maximum value and if so,
|
# Check if the population has already reached the maximum value and if so,
|
||||||
# break the cycle. If this check is disabled, the algorithm will take
|
# break the cycle. If this check is disabled, the algorithm will take
|
||||||
# forever to compute large strings, but will also calculate small strings in
|
# forever to compute large strings, but will also calculate small strings in
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import typing
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
Vector = Union[Iterable[float], Iterable[int], np.ndarray]
|
Vector = typing.Union[Iterable[float], Iterable[int], np.ndarray] # noqa: UP007
|
||||||
VectorOut = Union[np.float64, int, float]
|
VectorOut = typing.Union[np.float64, int, float] # noqa: UP007
|
||||||
|
|
||||||
|
|
||||||
def euclidean_distance(vector_1: Vector, vector_2: Vector) -> VectorOut:
|
def euclidean_distance(vector_1: Vector, vector_2: Vector) -> VectorOut:
|
||||||
|
@ -147,6 +147,6 @@ if __name__ == "__main__":
|
|||||||
# Print results
|
# Print results
|
||||||
print()
|
print()
|
||||||
print("Results: ")
|
print("Results: ")
|
||||||
print(f"Horizontal Distance: {str(horizontal_distance(init_vel, angle))} [m]")
|
print(f"Horizontal Distance: {horizontal_distance(init_vel, angle)!s} [m]")
|
||||||
print(f"Maximum Height: {str(max_height(init_vel, angle))} [m]")
|
print(f"Maximum Height: {max_height(init_vel, angle)!s} [m]")
|
||||||
print(f"Total Time: {str(total_time(init_vel, angle))} [s]")
|
print(f"Total Time: {total_time(init_vel, angle)!s} [s]")
|
||||||
|
@ -13,11 +13,9 @@ class TreeNode:
|
|||||||
self.left = None
|
self.left = None
|
||||||
|
|
||||||
|
|
||||||
def build_tree():
|
def build_tree() -> TreeNode:
|
||||||
print("\n********Press N to stop entering at any point of time********\n")
|
print("\n********Press N to stop entering at any point of time********\n")
|
||||||
check = input("Enter the value of the root node: ").strip().lower() or "n"
|
check = input("Enter the value of the root node: ").strip().lower()
|
||||||
if check == "n":
|
|
||||||
return None
|
|
||||||
q: queue.Queue = queue.Queue()
|
q: queue.Queue = queue.Queue()
|
||||||
tree_node = TreeNode(int(check))
|
tree_node = TreeNode(int(check))
|
||||||
q.put(tree_node)
|
q.put(tree_node)
|
||||||
@ -37,7 +35,7 @@ def build_tree():
|
|||||||
right_node = TreeNode(int(check))
|
right_node = TreeNode(int(check))
|
||||||
node_found.right = right_node
|
node_found.right = right_node
|
||||||
q.put(right_node)
|
q.put(right_node)
|
||||||
return None
|
raise
|
||||||
|
|
||||||
|
|
||||||
def pre_order(node: TreeNode) -> None:
|
def pre_order(node: TreeNode) -> None:
|
||||||
@ -272,7 +270,7 @@ if __name__ == "__main__":
|
|||||||
doctest.testmod()
|
doctest.testmod()
|
||||||
print(prompt("Binary Tree Traversals"))
|
print(prompt("Binary Tree Traversals"))
|
||||||
|
|
||||||
node = build_tree()
|
node: TreeNode = build_tree()
|
||||||
print(prompt("Pre Order Traversal"))
|
print(prompt("Pre Order Traversal"))
|
||||||
pre_order(node)
|
pre_order(node)
|
||||||
print(prompt() + "\n")
|
print(prompt() + "\n")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user