mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-12-18 01:00:15 +00:00
Compare commits
6 Commits
2ca6733795
...
f82260cbce
Author | SHA1 | Date | |
---|---|---|---|
|
f82260cbce | ||
|
e3bd7721c8 | ||
|
e3f3d668be | ||
|
3e9ca92ca9 | ||
|
17264a496b | ||
|
adda95ea58 |
|
@ -16,7 +16,7 @@ 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.7.1
|
rev: v0.7.3
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
|
@ -29,7 +29,7 @@ repos:
|
||||||
- tomli
|
- tomli
|
||||||
|
|
||||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||||
rev: "v2.4.3"
|
rev: "v2.5.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyproject-fmt
|
- id: pyproject-fmt
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ repos:
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
|
||||||
- repo: https://github.com/abravalheri/validate-pyproject
|
- repo: https://github.com/abravalheri/validate-pyproject
|
||||||
rev: v0.22
|
rev: v0.23
|
||||||
hooks:
|
hooks:
|
||||||
- id: validate-pyproject
|
- id: validate-pyproject
|
||||||
|
|
||||||
|
|
|
@ -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: set(sum(units[s], [])) - {s} for s in squares} # noqa: RUF017
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -172,13 +193,15 @@ def solved(values):
|
||||||
|
|
||||||
def from_file(filename, sep="\n"):
|
def from_file(filename, sep="\n"):
|
||||||
"Parse a file into a list of strings, separated by sep."
|
"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):
|
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])):
|
||||||
|
@ -190,7 +213,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
|
||||||
|
|
|
@ -29,6 +29,12 @@ def sigmoid(vector: np.ndarray) -> np.ndarray:
|
||||||
|
|
||||||
>>> sigmoid(np.array([0.0]))
|
>>> sigmoid(np.array([0.0]))
|
||||||
array([0.5])
|
array([0.5])
|
||||||
|
|
||||||
|
>>> sigmoid(np.array([100.0]))
|
||||||
|
array([1.])
|
||||||
|
|
||||||
|
>>> sigmoid(np.array([-100.0]))
|
||||||
|
array([3.72007598e-44])
|
||||||
"""
|
"""
|
||||||
return 1 / (1 + np.exp(-vector))
|
return 1 / (1 + np.exp(-vector))
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python3
|
#!python
|
||||||
import os
|
import os
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user