mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-22 09:12:08 +00:00
Compare commits
9 Commits
c8ac730982
...
be26bd0cd3
Author | SHA1 | Date | |
---|---|---|---|
|
be26bd0cd3 | ||
|
6c92c5a539 | ||
|
13e4d3e76c | ||
|
c666db3729 | ||
|
9fb51b4169 | ||
|
2e2580031f | ||
|
0f127aa03e | ||
|
5da5a7dc87 | ||
|
852038b3bf |
|
@ -16,13 +16,13 @@ repos:
|
||||||
- id: auto-walrus
|
- id: auto-walrus
|
||||||
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.9.2
|
rev: v0.9.3
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
|
|
||||||
- repo: https://github.com/codespell-project/codespell
|
- repo: https://github.com/codespell-project/codespell
|
||||||
rev: v2.3.0
|
rev: v2.4.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: codespell
|
- id: codespell
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
|
|
|
@ -863,6 +863,7 @@
|
||||||
* [Nested Brackets](other/nested_brackets.py)
|
* [Nested Brackets](other/nested_brackets.py)
|
||||||
* [Number Container System](other/number_container_system.py)
|
* [Number Container System](other/number_container_system.py)
|
||||||
* [Password](other/password.py)
|
* [Password](other/password.py)
|
||||||
|
* [Pipeline](other/pipeline.py)
|
||||||
* [Quine](other/quine.py)
|
* [Quine](other/quine.py)
|
||||||
* [Scoring Algorithm](other/scoring_algorithm.py)
|
* [Scoring Algorithm](other/scoring_algorithm.py)
|
||||||
* [Sdes](other/sdes.py)
|
* [Sdes](other/sdes.py)
|
||||||
|
|
|
@ -88,7 +88,7 @@ def __prepare(
|
||||||
...
|
...
|
||||||
KeyError: 'Length of alphabet has to be 27.'
|
KeyError: 'Length of alphabet has to be 27.'
|
||||||
|
|
||||||
Testing with punctuations that are not in the given alphabet
|
Testing with punctuation not in the given alphabet
|
||||||
|
|
||||||
>>> __prepare('am i a boy?','abCdeFghijkLmnopqrStuVwxYZ+')
|
>>> __prepare('am i a boy?','abCdeFghijkLmnopqrStuVwxYZ+')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
|
@ -128,7 +128,7 @@ def encrypt_message(
|
||||||
encrypt_message
|
encrypt_message
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Encrypts a message using the trifid_cipher. Any punctuatuions that
|
Encrypts a message using the trifid_cipher. Any punctuatuion chars that
|
||||||
would be used should be added to the alphabet.
|
would be used should be added to the alphabet.
|
||||||
|
|
||||||
PARAMETERS
|
PARAMETERS
|
||||||
|
|
|
@ -9,7 +9,9 @@ import time
|
||||||
|
|
||||||
|
|
||||||
def cross(items_a, items_b):
|
def cross(items_a, items_b):
|
||||||
"Cross product of elements in A and elements in B."
|
"""
|
||||||
|
Cross product of elements in A and elements in B.
|
||||||
|
"""
|
||||||
return [a + b for a in items_a for b in items_b]
|
return [a + b for a in items_a for b in items_b]
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +29,7 @@ peers = {s: {x for u in units[s] for x in u} - {s} for s in squares}
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
"A set of unit tests."
|
"""A set of unit tests."""
|
||||||
assert len(squares) == 81
|
assert len(squares) == 81
|
||||||
assert len(unitlist) == 27
|
assert len(unitlist) == 27
|
||||||
assert all(len(units[s]) == 3 for s in squares)
|
assert all(len(units[s]) == 3 for s in squares)
|
||||||
|
@ -47,8 +49,10 @@ def test():
|
||||||
|
|
||||||
|
|
||||||
def parse_grid(grid):
|
def parse_grid(grid):
|
||||||
"""Convert grid to a dict of possible values, {square: digits}, or
|
"""
|
||||||
return False if a contradiction is detected."""
|
Convert grid to a dict of possible values, {square: digits}, or
|
||||||
|
return False if a contradiction is detected.
|
||||||
|
"""
|
||||||
## To start, every square can be any digit; then assign values from the grid.
|
## To start, every square can be any digit; then assign values from the grid.
|
||||||
values = {s: digits for s in squares}
|
values = {s: digits for s in squares}
|
||||||
for s, d in grid_values(grid).items():
|
for s, d in grid_values(grid).items():
|
||||||
|
@ -58,15 +62,19 @@ def parse_grid(grid):
|
||||||
|
|
||||||
|
|
||||||
def grid_values(grid):
|
def grid_values(grid):
|
||||||
"Convert grid into a dict of {square: char} with '0' or '.' for empties."
|
"""
|
||||||
|
Convert grid into a dict of {square: char} with '0' or '.' for empties.
|
||||||
|
"""
|
||||||
chars = [c for c in grid if c in digits or c in "0."]
|
chars = [c for c in grid if c in digits or c in "0."]
|
||||||
assert len(chars) == 81
|
assert len(chars) == 81
|
||||||
return dict(zip(squares, chars))
|
return dict(zip(squares, chars))
|
||||||
|
|
||||||
|
|
||||||
def assign(values, s, d):
|
def assign(values, s, d):
|
||||||
"""Eliminate all the other values (except d) from values[s] and propagate.
|
"""
|
||||||
Return values, except return False if a contradiction is detected."""
|
Eliminate all the other values (except d) from values[s] and propagate.
|
||||||
|
Return values, except return False if a contradiction is detected.
|
||||||
|
"""
|
||||||
other_values = values[s].replace(d, "")
|
other_values = values[s].replace(d, "")
|
||||||
if all(eliminate(values, s, d2) for d2 in other_values):
|
if all(eliminate(values, s, d2) for d2 in other_values):
|
||||||
return values
|
return values
|
||||||
|
@ -75,8 +83,10 @@ def assign(values, s, d):
|
||||||
|
|
||||||
|
|
||||||
def eliminate(values, s, d):
|
def eliminate(values, s, d):
|
||||||
"""Eliminate d from values[s]; propagate when values or places <= 2.
|
"""
|
||||||
Return values, except return False if a contradiction is detected."""
|
Eliminate d from values[s]; propagate when values or places <= 2.
|
||||||
|
Return values, except return False if a contradiction is detected.
|
||||||
|
"""
|
||||||
if d not in values[s]:
|
if d not in values[s]:
|
||||||
return values ## Already eliminated
|
return values ## Already eliminated
|
||||||
values[s] = values[s].replace(d, "")
|
values[s] = values[s].replace(d, "")
|
||||||
|
@ -99,7 +109,9 @@ def eliminate(values, s, d):
|
||||||
|
|
||||||
|
|
||||||
def display(values):
|
def display(values):
|
||||||
"Display these values as a 2-D grid."
|
"""
|
||||||
|
Display these values as a 2-D grid.
|
||||||
|
"""
|
||||||
width = 1 + max(len(values[s]) for s in squares)
|
width = 1 + max(len(values[s]) for s in squares)
|
||||||
line = "+".join(["-" * (width * 3)] * 3)
|
line = "+".join(["-" * (width * 3)] * 3)
|
||||||
for r in rows:
|
for r in rows:
|
||||||
|
@ -114,11 +126,14 @@ def display(values):
|
||||||
|
|
||||||
|
|
||||||
def solve(grid):
|
def solve(grid):
|
||||||
|
"""
|
||||||
|
Solve the grid.
|
||||||
|
"""
|
||||||
return search(parse_grid(grid))
|
return search(parse_grid(grid))
|
||||||
|
|
||||||
|
|
||||||
def some(seq):
|
def some(seq):
|
||||||
"Return some element of seq that is true."
|
"""Return some element of seq that is true."""
|
||||||
for e in seq:
|
for e in seq:
|
||||||
if e:
|
if e:
|
||||||
return e
|
return e
|
||||||
|
@ -126,7 +141,9 @@ def some(seq):
|
||||||
|
|
||||||
|
|
||||||
def search(values):
|
def search(values):
|
||||||
"Using depth-first search and propagation, try all possible values."
|
"""
|
||||||
|
Using depth-first search and propagation, try all possible values.
|
||||||
|
"""
|
||||||
if values is False:
|
if values is False:
|
||||||
return False ## Failed earlier
|
return False ## Failed earlier
|
||||||
if all(len(values[s]) == 1 for s in squares):
|
if all(len(values[s]) == 1 for s in squares):
|
||||||
|
@ -137,9 +154,11 @@ def search(values):
|
||||||
|
|
||||||
|
|
||||||
def solve_all(grids, name="", showif=0.0):
|
def solve_all(grids, name="", showif=0.0):
|
||||||
"""Attempt to solve a sequence of grids. Report results.
|
"""
|
||||||
|
Attempt to solve a sequence of grids. Report results.
|
||||||
When showif is a number of seconds, display puzzles that take longer.
|
When showif is a number of seconds, display puzzles that take longer.
|
||||||
When showif is None, don't display any puzzles."""
|
When showif is None, don't display any puzzles.
|
||||||
|
"""
|
||||||
|
|
||||||
def time_solve(grid):
|
def time_solve(grid):
|
||||||
start = time.monotonic()
|
start = time.monotonic()
|
||||||
|
@ -162,7 +181,9 @@ def solve_all(grids, name="", showif=0.0):
|
||||||
|
|
||||||
|
|
||||||
def solved(values):
|
def solved(values):
|
||||||
"A puzzle is solved if each unit is a permutation of the digits 1 to 9."
|
"""
|
||||||
|
A puzzle is solved if each unit is a permutation of the digits 1 to 9.
|
||||||
|
"""
|
||||||
|
|
||||||
def unitsolved(unit):
|
def unitsolved(unit):
|
||||||
return {values[s] for s in unit} == set(digits)
|
return {values[s] for s in unit} == set(digits)
|
||||||
|
@ -177,9 +198,11 @@ def from_file(filename, sep="\n"):
|
||||||
|
|
||||||
|
|
||||||
def random_puzzle(assignments=17):
|
def random_puzzle(assignments=17):
|
||||||
"""Make a random puzzle with N or more assignments. Restart on contradictions.
|
"""
|
||||||
|
Make a random puzzle with N or more assignments. Restart on contradictions.
|
||||||
Note the resulting puzzle is not guaranteed to be solvable, but empirically
|
Note the resulting puzzle is not guaranteed to be solvable, but empirically
|
||||||
about 99.8% of them are solvable. Some have multiple solutions."""
|
about 99.8% of them are solvable. Some have multiple solutions.
|
||||||
|
"""
|
||||||
values = {s: digits for s in squares}
|
values = {s: digits for s in squares}
|
||||||
for s in shuffled(squares):
|
for s in shuffled(squares):
|
||||||
if not assign(values, s, random.choice(values[s])):
|
if not assign(values, s, random.choice(values[s])):
|
||||||
|
@ -191,7 +214,9 @@ def random_puzzle(assignments=17):
|
||||||
|
|
||||||
|
|
||||||
def shuffled(seq):
|
def shuffled(seq):
|
||||||
"Return a randomly shuffled copy of the input sequence."
|
"""
|
||||||
|
Return a randomly shuffled copy of the input sequence.
|
||||||
|
"""
|
||||||
seq = list(seq)
|
seq = list(seq)
|
||||||
random.shuffle(seq)
|
random.shuffle(seq)
|
||||||
return seq
|
return seq
|
||||||
|
|
|
@ -221,6 +221,10 @@ def del_node(root: MyNode, data: Any) -> MyNode | None:
|
||||||
else:
|
else:
|
||||||
root.set_right(del_node(right_child, data))
|
root.set_right(del_node(right_child, data))
|
||||||
|
|
||||||
|
# Re-fetch left_child and right_child references
|
||||||
|
left_child = root.get_left()
|
||||||
|
right_child = root.get_right()
|
||||||
|
|
||||||
if get_height(right_child) - get_height(left_child) == 2:
|
if get_height(right_child) - get_height(left_child) == 2:
|
||||||
assert right_child is not None
|
assert right_child is not None
|
||||||
if get_height(right_child.get_right()) > get_height(right_child.get_left()):
|
if get_height(right_child.get_right()) > get_height(right_child.get_left()):
|
||||||
|
|
46
other/pipeline.py
Normal file
46
other/pipeline.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
from collections.abc import Callable, Sequence
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
class Pipeline:
|
||||||
|
"""
|
||||||
|
Functional Programming implementation of a Pipeline with Unix Pipe Syntax.
|
||||||
|
Instead of using the "dot" notation for applying a function on a given object,
|
||||||
|
it uses `|` inspired from unix pipeline.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
>>> pipeline = Pipeline()
|
||||||
|
>>> pipeline = pipeline | (lambda x: x + 1) | (lambda x: x * 2)
|
||||||
|
>>> pipeline(1)
|
||||||
|
4
|
||||||
|
>>> pipeline = Pipeline() | (lambda x: x * x) | (lambda x: x - 3)
|
||||||
|
>>> pipeline(3)
|
||||||
|
6
|
||||||
|
>>> from functools import reduce
|
||||||
|
>>> def f1(ls): return map(lambda x: x**2, ls)
|
||||||
|
>>> def f2(ls): return filter(lambda x: x % 2 == 0, ls)
|
||||||
|
>>> def f3(ls): return reduce(lambda x, y: x + y, ls)
|
||||||
|
>>> pipeline = Pipeline() | f1 | f2 | f3
|
||||||
|
>>> pipeline([1, 2, 3, 4])
|
||||||
|
20
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, f_ls: Sequence[Callable] | None = None) -> None:
|
||||||
|
self._f_ls = f_ls or []
|
||||||
|
|
||||||
|
def __or__(self, other: Callable) -> "Pipeline":
|
||||||
|
return Pipeline(f_ls=[*self._f_ls, other])
|
||||||
|
|
||||||
|
def __call__(self, input_object: T, f_ls_: Sequence[Callable] | None = None) -> Any:
|
||||||
|
f_ls = f_ls_ or self._f_ls
|
||||||
|
if len(f_ls) == 1:
|
||||||
|
return f_ls[0](input_object)
|
||||||
|
return self(f_ls[0](input_object), f_ls_=f_ls[1:])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import doctest
|
||||||
|
|
||||||
|
doctest.testmod()
|
|
@ -159,7 +159,7 @@ lint.pylint.max-returns = 8 # default: 6
|
||||||
lint.pylint.max-statements = 88 # default: 50
|
lint.pylint.max-statements = 88 # default: 50
|
||||||
|
|
||||||
[tool.codespell]
|
[tool.codespell]
|
||||||
ignore-words-list = "3rt,ans,bitap,crate,damon,fo,followings,hist,iff,kwanza,manuel,mater,secant,som,sur,tim,toi,zar"
|
ignore-words-list = "3rt,abd,aer,ans,bitap,crate,damon,fo,followings,hist,iff,kwanza,manuel,mater,secant,som,sur,tim,toi,zar"
|
||||||
skip = "./.*,*.json,*.lock,ciphers/prehistoric_men.txt,project_euler/problem_022/p022_names.txt,pyproject.toml,strings/dictionary.txt,strings/words.txt"
|
skip = "./.*,*.json,*.lock,ciphers/prehistoric_men.txt,project_euler/problem_022/p022_names.txt,pyproject.toml,strings/dictionary.txt,strings/words.txt"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
|
|
|
@ -85,6 +85,8 @@ def bubble_sort_recursive(collection: list[Any]) -> list[Any]:
|
||||||
[1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7]
|
[1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7]
|
||||||
>>> bubble_sort_recursive([1, 3.3, 5, 7.7, 2, 4.4, 6])
|
>>> bubble_sort_recursive([1, 3.3, 5, 7.7, 2, 4.4, 6])
|
||||||
[1, 2, 3.3, 4.4, 5, 6, 7.7]
|
[1, 2, 3.3, 4.4, 5, 6, 7.7]
|
||||||
|
>>> bubble_sort_recursive(['a', 'Z', 'B', 'C', 'A', 'c'])
|
||||||
|
['A', 'B', 'C', 'Z', 'a', 'c']
|
||||||
>>> import random
|
>>> import random
|
||||||
>>> collection_arg = random.sample(range(-50, 50), 100)
|
>>> collection_arg = random.sample(range(-50, 50), 100)
|
||||||
>>> bubble_sort_recursive(collection_arg) == sorted(collection_arg)
|
>>> bubble_sort_recursive(collection_arg) == sorted(collection_arg)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user