Merge branch 'TheAlgorithms:master' into ga_optimization

This commit is contained in:
UTSAV SINGHAL 2024-12-02 14:20:27 +05:30 committed by GitHub
commit cdb28e53e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 93 additions and 89 deletions

View File

@ -16,7 +16,7 @@ repos:
- id: auto-walrus
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
rev: v0.8.0
hooks:
- id: ruff
- id: ruff-format
@ -29,7 +29,7 @@ repos:
- tomli
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "2.3.0"
rev: "v2.5.0"
hooks:
- id: pyproject-fmt
@ -42,12 +42,12 @@ repos:
pass_filenames: false
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.20.2
rev: v0.23
hooks:
- id: validate-pyproject
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.2
rev: v1.13.0
hooks:
- id: mypy
args:

View File

@ -58,10 +58,8 @@ def new_generation(cells: list[list[int]]) -> list[list[int]]:
# 3. All other live cells die in the next generation.
# Similarly, all other dead cells stay dead.
alive = cells[i][j] == 1
if (
(alive and 2 <= neighbour_count <= 3)
or not alive
and neighbour_count == 3
if (alive and 2 <= neighbour_count <= 3) or (
not alive and neighbour_count == 3
):
next_generation_row.append(1)
else:

View File

@ -24,7 +24,7 @@ import string
from collections.abc import Generator, Iterable
def chunker(seq: Iterable[str], size: int) -> Generator[tuple[str, ...], None, None]:
def chunker(seq: Iterable[str], size: int) -> Generator[tuple[str, ...]]:
it = iter(seq)
while True:
chunk = tuple(itertools.islice(it, size))

View File

@ -10,7 +10,7 @@ def remove_duplicates(key: str) -> str:
key_no_dups = ""
for ch in key:
if ch == " " or ch not in key_no_dups and ch.isalpha():
if ch == " " or (ch not in key_no_dups and ch.isalpha()):
key_no_dups += ch
return key_no_dups

View File

@ -52,10 +52,8 @@ def decrypt_message(key: int, message: str) -> str:
plain_text[col] += symbol
col += 1
if (
(col == num_cols)
or (col == num_cols - 1)
and (row >= num_rows - num_shaded_boxes)
if (col == num_cols) or (
(col == num_cols - 1) and (row >= num_rows - num_shaded_boxes)
):
col = 0
row += 1

View File

@ -35,8 +35,8 @@ def add_key_to_lexicon(
lexicon[curr_string + "0"] = last_match_id
if math.log2(index).is_integer():
for curr_key in lexicon:
lexicon[curr_key] = "0" + lexicon[curr_key]
for curr_key, value in lexicon.items():
lexicon[curr_key] = f"0{value}"
lexicon[curr_string + "1"] = bin(index)[2:]

View File

@ -156,7 +156,7 @@ def solve_all(grids, name="", showif=0.0):
times, results = zip(*[time_solve(grid) for grid in grids])
if (n := len(grids)) > 1:
print(
"Solved %d of %d %s puzzles (avg %.2f secs (%d Hz), max %.2f secs)."
"Solved %d of %d %s puzzles (avg %.2f secs (%d Hz), max %.2f secs)." # noqa: UP031
% (sum(results), n, name, sum(times) / n, n / sum(times), max(times))
)
@ -172,7 +172,7 @@ def solved(values):
def from_file(filename, sep="\n"):
"Parse a file into a list of strings, separated by sep."
return open(filename).read().strip().split(sep) # noqa: SIM115
return open(filename).read().strip().split(sep)
def random_puzzle(assignments=17):

View File

@ -30,7 +30,7 @@ def make_tree() -> Node | None:
return tree
def preorder(root: Node | None) -> Generator[int, None, None]:
def preorder(root: Node | None) -> Generator[int]:
"""
Pre-order traversal visits root node, left subtree, right subtree.
>>> list(preorder(make_tree()))
@ -43,7 +43,7 @@ def preorder(root: Node | None) -> Generator[int, None, None]:
yield from preorder(root.right)
def postorder(root: Node | None) -> Generator[int, None, None]:
def postorder(root: Node | None) -> Generator[int]:
"""
Post-order traversal visits left subtree, right subtree, root node.
>>> list(postorder(make_tree()))
@ -56,7 +56,7 @@ def postorder(root: Node | None) -> Generator[int, None, None]:
yield root.data
def inorder(root: Node | None) -> Generator[int, None, None]:
def inorder(root: Node | None) -> Generator[int]:
"""
In-order traversal visits left subtree, root node, right subtree.
>>> list(inorder(make_tree()))
@ -69,7 +69,7 @@ def inorder(root: Node | None) -> Generator[int, None, None]:
yield from inorder(root.right)
def reverse_inorder(root: Node | None) -> Generator[int, None, None]:
def reverse_inorder(root: Node | None) -> Generator[int]:
"""
Reverse in-order traversal visits right subtree, root node, left subtree.
>>> list(reverse_inorder(make_tree()))
@ -93,7 +93,7 @@ def height(root: Node | None) -> int:
return (max(height(root.left), height(root.right)) + 1) if root else 0
def level_order(root: Node | None) -> Generator[int, None, None]:
def level_order(root: Node | None) -> Generator[int]:
"""
Returns a list of nodes value from a whole binary tree in Level Order Traverse.
Level Order traverse: Visit nodes of the tree level-by-level.
@ -116,9 +116,7 @@ def level_order(root: Node | None) -> Generator[int, None, None]:
process_queue.append(node.right)
def get_nodes_from_left_to_right(
root: Node | None, level: int
) -> Generator[int, None, None]:
def get_nodes_from_left_to_right(root: Node | None, level: int) -> Generator[int]:
"""
Returns a list of nodes value from a particular level:
Left to right direction of the binary tree.
@ -128,7 +126,7 @@ def get_nodes_from_left_to_right(
[2, 3]
"""
def populate_output(root: Node | None, level: int) -> Generator[int, None, None]:
def populate_output(root: Node | None, level: int) -> Generator[int]:
if not root:
return
if level == 1:
@ -140,9 +138,7 @@ def get_nodes_from_left_to_right(
yield from populate_output(root, level)
def get_nodes_from_right_to_left(
root: Node | None, level: int
) -> Generator[int, None, None]:
def get_nodes_from_right_to_left(root: Node | None, level: int) -> Generator[int]:
"""
Returns a list of nodes value from a particular level:
Right to left direction of the binary tree.
@ -152,7 +148,7 @@ def get_nodes_from_right_to_left(
[3, 2]
"""
def populate_output(root: Node | None, level: int) -> Generator[int, None, None]:
def populate_output(root: Node | None, level: int) -> Generator[int]:
if not root:
return
if level == 1:
@ -164,7 +160,7 @@ def get_nodes_from_right_to_left(
yield from populate_output(root, level)
def zigzag(root: Node | None) -> Generator[int, None, None]:
def zigzag(root: Node | None) -> Generator[int]:
"""
ZigZag traverse:
Returns a list of nodes value from left to right and right to left, alternatively.

View File

@ -12,7 +12,7 @@ class _DoublyLinkedBase:
"""A Private class (to be inherited)"""
class _Node:
__slots__ = "_prev", "_data", "_next"
__slots__ = "_data", "_next", "_prev"
def __init__(self, link_p, element, link_n):
self._prev = link_p

View File

@ -33,7 +33,7 @@ class Deque:
the number of nodes
"""
__slots__ = ("_front", "_back", "_len")
__slots__ = ("_back", "_front", "_len")
@dataclass
class _Node:

0
docs/source/__init__.py Normal file
View File

View File

@ -6,7 +6,7 @@ Source: https://en.wikipedia.org/wiki/Electrical_impedance
from __future__ import annotations
from math import pow, sqrt
from math import pow, sqrt # noqa: A004
def electrical_impedance(

View File

@ -194,10 +194,8 @@ def city_select(
IndexError: list index out of range
"""
probabilities = []
for city in unvisited_cities:
city_distance = distance(
unvisited_cities[city], next(iter(current_city.values()))
)
for city, value in unvisited_cities.items():
city_distance = distance(value, next(iter(current_city.values())))
probability = (pheromone[city][next(iter(current_city.keys()))] ** alpha) * (
(1 / city_distance) ** beta
)

View File

@ -133,18 +133,18 @@ def dijk(g, s):
if len(known) == len(g) - 1:
break
mini = 100000
for i in dist:
if i not in known and dist[i] < mini:
mini = dist[i]
u = i
for key, value in dist:
if key not in known and value < mini:
mini = value
u = key
known.add(u)
for v in g[u]:
if v[0] not in known and dist[u] + v[1] < dist.get(v[0], 100000):
dist[v[0]] = dist[u] + v[1]
path[v[0]] = u
for i in dist:
if i != s:
print(dist[i])
for key, value in dist.items():
if key != s:
print(value)
"""
@ -255,10 +255,10 @@ def prim(g, s):
if len(known) == len(g) - 1:
break
mini = 100000
for i in dist:
if i not in known and dist[i] < mini:
mini = dist[i]
u = i
for key, value in dist.items():
if key not in known and value < mini:
mini = value
u = key
known.add(u)
for v in g[u]:
if v[0] not in known and v[1] < dist.get(v[0], 100000):

View File

@ -185,12 +185,12 @@ class Graph:
if cheap_edge[set2] == -1 or cheap_edge[set2][2] > weight:
cheap_edge[set2] = [head, tail, weight]
for vertex in cheap_edge:
if cheap_edge[vertex] != -1:
head, tail, weight = cheap_edge[vertex]
for head_tail_weight in cheap_edge.values():
if head_tail_weight != -1:
head, tail, weight = head_tail_weight
if union_find.find(head) != union_find.find(tail):
union_find.union(head, tail)
mst_edges.append(cheap_edge[vertex])
mst_edges.append(head_tail_weight)
num_components = num_components - 1
mst = Graph.build(edges=mst_edges)
return mst

View File

@ -131,7 +131,7 @@ def preprocess(message: bytes) -> bytes:
return bit_string
def get_block_words(bit_string: bytes) -> Generator[list[int], None, None]:
def get_block_words(bit_string: bytes) -> Generator[list[int]]:
"""
Splits bit string into blocks of 512 chars and yields each block as a list
of 32-bit words

View File

@ -107,8 +107,8 @@ def create_tree(data_set: list, min_sup: int = 1) -> tuple[TreeNode, dict]:
if not (freq_item_set := set(header_table)):
return TreeNode("Null Set", 1, None), {}
for k in header_table:
header_table[k] = [header_table[k], None]
for key, value in header_table.items():
header_table[key] = [value, None]
fp_tree = TreeNode("Null Set", 1, None) # Parent is None for the root node
for tran_set in data_set:

View File

@ -17,7 +17,7 @@ from __future__ import annotations
from collections.abc import Generator
def collatz_sequence(n: int) -> Generator[int, None, None]:
def collatz_sequence(n: int) -> Generator[int]:
"""
Generate the Collatz sequence starting at n.
>>> tuple(collatz_sequence(2.1))

View File

@ -2,7 +2,7 @@ import math
from collections.abc import Generator
def slow_primes(max_n: int) -> Generator[int, None, None]:
def slow_primes(max_n: int) -> Generator[int]:
"""
Return a list of all primes numbers up to max.
>>> list(slow_primes(0))
@ -29,7 +29,7 @@ def slow_primes(max_n: int) -> Generator[int, None, None]:
yield i
def primes(max_n: int) -> Generator[int, None, None]:
def primes(max_n: int) -> Generator[int]:
"""
Return a list of all primes numbers up to max.
>>> list(primes(0))
@ -58,7 +58,7 @@ def primes(max_n: int) -> Generator[int, None, None]:
yield i
def fast_primes(max_n: int) -> Generator[int, None, None]:
def fast_primes(max_n: int) -> Generator[int]:
"""
Return a list of all primes numbers up to max.
>>> list(fast_primes(0))

View File

@ -6,7 +6,7 @@ Find the volume of various shapes.
from __future__ import annotations
from math import pi, pow
from math import pi, pow # noqa: A004
def vol_cube(side_length: float) -> float:

View File

@ -61,9 +61,8 @@ def _extract_images(f):
with gzip.GzipFile(fileobj=f) as bytestream:
magic = _read32(bytestream)
if magic != 2051:
raise ValueError(
"Invalid magic number %d in MNIST image file: %s" % (magic, f.name)
)
msg = f"Invalid magic number {magic} in MNIST image file: {f.name}"
raise ValueError(msg)
num_images = _read32(bytestream)
rows = _read32(bytestream)
cols = _read32(bytestream)
@ -102,9 +101,8 @@ def _extract_labels(f, one_hot=False, num_classes=10):
with gzip.GzipFile(fileobj=f) as bytestream:
magic = _read32(bytestream)
if magic != 2049:
raise ValueError(
"Invalid magic number %d in MNIST label file: %s" % (magic, f.name)
)
msg = f"Invalid magic number {magic} in MNIST label file: {f.name}"
raise ValueError(msg)
num_items = _read32(bytestream)
buf = bytestream.read(num_items)
labels = np.frombuffer(buf, dtype=np.uint8)

View File

@ -1,7 +1,3 @@
from math import pow, sqrt
from scipy.constants import G, c, pi
"""
These two functions will return the radii of impact for a target object
of mass M and radius R as well as it's effective cross sectional area sigma.
@ -14,9 +10,12 @@ body in order to hit it, as R_capture>R_target. Astronomers refer to the effect
cross section for capture as sigma=π*R_capture**2.
This algorithm does not account for an N-body problem.
"""
from math import pow, sqrt # noqa: A004
from scipy.constants import G, c, pi
def capture_radii(
target_body_radius: float, target_body_mass: float, projectile_velocity: float

View File

@ -14,7 +14,7 @@ m2 = Molar mass of the second gas.
(Description adapted from https://en.wikipedia.org/wiki/Graham%27s_law)
"""
from math import pow, sqrt
from math import pow, sqrt # noqa: A004
def validate(*values: float) -> bool:

View File

@ -27,7 +27,7 @@ digits?
from collections.abc import Generator
def fibonacci_generator() -> Generator[int, None, None]:
def fibonacci_generator() -> Generator[int]:
"""
A generator that produces numbers in the Fibonacci sequence

View File

@ -24,7 +24,7 @@ from functools import lru_cache
def unique_prime_factors(n: int) -> set:
"""
Find unique prime factors of an integer.
Tests include sorting because only the set really matters,
Tests include sorting because only the set matters,
not the order in which it is produced.
>>> sorted(set(unique_prime_factors(14)))
[2, 7]
@ -58,7 +58,7 @@ def upf_len(num: int) -> int:
def equality(iterable: list) -> bool:
"""
Check equality of ALL elements in an iterable
Check the equality of ALL elements in an iterable
>>> equality([1, 2, 3, 4])
False
>>> equality([2, 2, 2, 2])
@ -69,7 +69,7 @@ def equality(iterable: list) -> bool:
return len(set(iterable)) in (0, 1)
def run(n: int) -> list:
def run(n: int) -> list[int]:
"""
Runs core process to find problem solution.
>>> run(3)
@ -77,7 +77,7 @@ def run(n: int) -> list:
"""
# Incrementor variable for our group list comprehension.
# This serves as the first number in each list of values
# This is the first number in each list of values
# to test.
base = 2
@ -85,7 +85,7 @@ def run(n: int) -> list:
# Increment each value of a generated range
group = [base + i for i in range(n)]
# Run elements through out unique_prime_factors function
# Run elements through the unique_prime_factors function
# Append our target number to the end.
checker = [upf_len(x) for x in group]
checker.append(n)
@ -98,7 +98,7 @@ def run(n: int) -> list:
base += 1
def solution(n: int = 4) -> int:
def solution(n: int = 4) -> int | None:
"""Return the first value of the first four consecutive integers to have four
distinct prime factors each.
>>> solution()

View File

@ -43,7 +43,7 @@ from __future__ import annotations
from collections.abc import Generator
def sieve() -> Generator[int, None, None]:
def sieve() -> Generator[int]:
"""
Returns a prime number generator using sieve method.
>>> type(sieve())

View File

@ -80,6 +80,7 @@ lint.ignore = [
"EM101", # Exception must not use a string literal, assign to variable first
"EXE001", # Shebang is present but file is not executable -- DO NOT FIX
"G004", # Logging statement uses f-string
"ISC001", # Conflicts with ruff format -- DO NOT FIX
"PLC1901", # `{}` can be simplified to `{}` as an empty string is falsey
"PLW060", # Using global for `{name}` but no assignment is done -- DO NOT FIX
"PLW2901", # PLW2901: Redefined loop variable -- FIX ME

16
scripts/find_git_conflicts.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
# Replace with your repository (format: owner/repo)
REPO="TheAlgorithms/Python"
# Fetch open pull requests with conflicts into a variable
echo "Checking for pull requests with conflicts in $REPO..."
prs=$(gh pr list --repo "$REPO" --state open --json number,title,mergeable --jq '.[] | select(.mergeable == "CONFLICTING") | {number, title}' --limit 500)
# Process each conflicting PR
echo "$prs" | jq -c '.[]' | while read -r pr; do
PR_NUMBER=$(echo "$pr" | jq -r '.number')
PR_TITLE=$(echo "$pr" | jq -r '.title')
echo "PR #$PR_NUMBER - $PR_TITLE has conflicts."
done

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!python
import os
try:

0
source/__init__.py Normal file
View File

View File

@ -67,7 +67,7 @@ def get_frequency_order(message: str) -> str:
freq_to_letter_str: dict[int, str] = {}
for freq in freq_to_letter:
for freq in freq_to_letter: # noqa: PLC0206
freq_to_letter[freq].sort(key=ETAOIN.find, reverse=True)
freq_to_letter_str[freq] = "".join(freq_to_letter[freq])

View File

@ -124,7 +124,7 @@ if __name__ == "__main__":
print("".join(string))
if op[0] == "C":
file.write("%-16s" % "Copy %c" % op[1])
file.write("%-16s" % "Copy %c" % op[1]) # noqa: UP031
file.write("\t\t\t" + "".join(string))
file.write("\r\n")
@ -132,7 +132,7 @@ if __name__ == "__main__":
elif op[0] == "R":
string[i] = op[2]
file.write("%-16s" % ("Replace %c" % op[1] + " with " + str(op[2])))
file.write("%-16s" % ("Replace %c" % op[1] + " with " + str(op[2]))) # noqa: UP031
file.write("\t\t" + "".join(string))
file.write("\r\n")
@ -140,7 +140,7 @@ if __name__ == "__main__":
elif op[0] == "D":
string.pop(i)
file.write("%-16s" % "Delete %c" % op[1])
file.write("%-16s" % "Delete %c" % op[1]) # noqa: UP031
file.write("\t\t\t" + "".join(string))
file.write("\r\n")
@ -148,7 +148,7 @@ if __name__ == "__main__":
else:
string.insert(i, op[1])
file.write("%-16s" % "Insert %c" % op[1])
file.write("%-16s" % "Insert %c" % op[1]) # noqa: UP031
file.write("\t\t\t" + "".join(string))
file.write("\r\n")

View File

@ -12,7 +12,7 @@ from bs4 import BeautifulSoup
url = "https://www.indeed.co.in/jobs?q=mobile+app+development&l="
def fetch_jobs(location: str = "mumbai") -> Generator[tuple[str, str], None, None]:
def fetch_jobs(location: str = "mumbai") -> Generator[tuple[str, str]]:
soup = BeautifulSoup(
requests.get(url + location, timeout=10).content, "html.parser"
)