22 - python & all web labs

This commit is contained in:
2026-05-02 20:27:02 +05:00
parent ef77f101fa
commit 19af922baf
5781 changed files with 770492 additions and 96 deletions

View File

@@ -1,8 +1,10 @@
M
M M M
M M M
M M M
MM
MMM MMMM
M M M
M M MMM
MMMM
MMM M M M
M M
MM M MM
MM MMMMM
M M MMM
M M
M M MMM

View File

@@ -1,65 +1,239 @@
from __future__ import annotations
import heapq
import os
import random
def create_file():
n = random.randint(5, 10)
maze = []
for _ in range(n):
row = "".join(["M" if random.random() < 0.3 else " " for _ in range(n)])
maze.append(row)
with open("maze.txt", "w") as f:
for row in maze:
f.write(row + "\n")
return n
WALL = "M"
def read_maze():
with open("maze.txt") as f:
maze = [list(line.rstrip("\n")) for line in f]
return maze
def _maze_path() -> str:
return os.path.join(os.path.dirname(__file__), "maze.txt")
def solve(maze, x, y, xc, yc, visited, length, best):
n = len(maze)
if x < 0 or y < 0 or x >= n or y >= n:
return
if maze[x][y] == "M" or visited[x][y]:
return
if length >= best[0]:
return
if x == xc and y == yc:
best[0] = min(best[0], length)
return
visited[x][y] = True
solve(maze, x + 1, y, xc, yc, visited, length + 1, best)
solve(maze, x - 1, y, xc, yc, visited, length + 1, best)
solve(maze, x, y + 1, xc, yc, visited, length + 1, best)
solve(maze, x, y - 1, xc, yc, visited, length + 1, best)
visited[x][y] = False
def _read_int(
prompt: str, *, min_value: int | None = None, max_value: int | None = None
) -> int:
while True:
try:
s = input(prompt).strip()
except EOFError:
raise
try:
v = int(s)
except ValueError:
print("Ошибка: нужно целое число.")
continue
if min_value is not None and v < min_value:
print(f"Ошибка: число должно быть не меньше {min_value}.")
continue
if max_value is not None and v > max_value:
print(f"Ошибка: число должно быть не больше {max_value}.")
continue
return v
while True:
print("\n1 - создать лабиринт\n2 - решить\n0 - выход")
try:
c = input("Выбор: ")
if c == "1":
n = create_file()
print("Файл создан. Размер:", n)
elif c == "2":
maze = read_maze()
n = len(maze)
x = int(input("Старт X: "))
y = int(input("Старт Y: "))
xc = int(input("Сыр X: "))
yc = int(input("Сыр Y: "))
visited = [[False] * n for _ in range(n)]
best = [10**9]
solve(maze, x, y, xc, yc, visited, 0, best)
if best[0] == 10**9:
print("Путь не найден")
def _normalize_grid(rows: list[str], n: int) -> list[str]:
if len(rows) != n:
raise ValueError(f"Ожидалось {n} строк, получено {len(rows)}.")
grid = [(r[:n] + (" " * max(0, n - len(r)))) for r in rows]
return grid
def read_maze_from_file(n: int) -> list[str]:
path = _maze_path()
if not os.path.exists(path):
raise FileNotFoundError("Файл maze.txt не найден.")
with open(path, "r", encoding="utf-8") as f:
rows = [ln.rstrip("\n") for ln in f.readlines()]
rows = rows[:n]
return _normalize_grid(rows, n)
def write_maze_to_file(grid: list[str]) -> None:
path = _maze_path()
with open(path, "w", encoding="utf-8") as f:
for r in grid:
f.write(r + "\n")
def print_maze_with_coords(grid: list[str]) -> None:
n = len(grid)
# Заголовок столбцов
print(" ", end="")
for j in range(n):
print(f"{j + 1:2}", end=" ")
print()
# Лабиринт с номерами строк
for i, row in enumerate(grid):
print(f"{i + 1:2} ", end="")
for cell in row:
print(f" {cell if cell != ' ' else '.'}", end=" ")
print()
def _is_exit(grid: list[str], i: int, j: int) -> bool:
n = len(grid)
return (i == 0 or j == 0 or i == n - 1 or j == n - 1) and grid[i][j] != WALL
def a_star_shortest_path(grid: list[str], start: tuple[int, int]) -> str:
n = len(grid)
sx, sy = start
if not (0 <= sx < n and 0 <= sy < n):
raise ValueError("Стартовые координаты вне лабиринта.")
if grid[sx][sy] == WALL:
raise ValueError("Стартовая клетка является стеной.")
exits = [(i, j) for i in range(n) for j in range(n) if _is_exit(grid, i, j)]
if not exits:
raise ValueError("В лабиринте нет выходов.")
if _is_exit(grid, sx, sy):
return ""
def h(i: int, j: int) -> int:
return min(abs(i - ei) + abs(j - ej) for ei, ej in exits)
inf = 10**9
gscore = [[inf] * n for _ in range(n)]
gscore[sx][sy] = 0
prev: list[list[tuple[int, int] | None]] = [[None] * n for _ in range(n)]
prev_move: list[list[str | None]] = [[None] * n for _ in range(n)]
heap: list[tuple[int, int, int, int]] = [(h(sx, sy), 0, sx, sy)]
closed = [[False] * n for _ in range(n)]
dirs = ((0, -1, "L"), (0, 1, "R"), (-1, 0, "U"), (1, 0, "D"))
while heap:
_, g, i, j = heapq.heappop(heap)
if closed[i][j]:
continue
closed[i][j] = True
if _is_exit(grid, i, j):
path: list[str] = []
ci, cj = i, j
while (ci, cj) != (sx, sy):
mv = prev_move[ci][cj]
p = prev[ci][cj]
if mv is None or p is None:
raise RuntimeError("Ошибка восстановления пути.")
path.append(mv)
ci, cj = p
path.reverse()
return "".join(path)
for di, dj, mv in dirs:
ni, nj = i + di, j + dj
if not (0 <= ni < n and 0 <= nj < n):
continue
if grid[ni][nj] == WALL:
continue
ng = g + 1
if ng < gscore[ni][nj]:
gscore[ni][nj] = ng
prev[ni][nj] = (i, j)
prev_move[ni][nj] = mv
heapq.heappush(heap, (ng + h(ni, nj), ng, ni, nj))
raise ValueError("Пути к выходу нет.")
def _random_grid(n: int, wall_percent: int) -> list[str]:
p = wall_percent / 100.0
rows: list[str] = []
for i in range(n):
row_chars: list[str] = []
for j in range(n):
if random.random() < p:
row_chars.append(WALL)
else:
print("Кратчайший путь:", best[0])
elif c == "0":
break
except:
print("Ошибка ввода")
row_chars.append(" ")
rows.append("".join(row_chars))
return rows
def _random_passage_cell(grid: list[str]) -> tuple[int, int]:
n = len(grid)
cells = [(i, j) for i in range(n) for j in range(n) if grid[i][j] != WALL]
if not cells:
raise ValueError("В лабиринте нет проходов.")
return random.choice(cells)
def generate_maze_file_interactive() -> None:
n = _read_int("Введите N (1..15): ", min_value=1, max_value=15)
wall_percent = _read_int(
"Введите процент стен M (0..90): ", min_value=0, max_value=90
)
tries = 0
while True:
tries += 1
grid = _random_grid(n, wall_percent)
for j in range(n):
if random.random() < 0.25:
grid[0] = grid[0][:j] + " " + grid[0][j + 1 :]
start = _random_passage_cell(grid)
try:
_ = a_star_shortest_path(grid, start)
write_maze_to_file(grid)
print(
f"Файл maze.txt создан. N={n}. Старт: X={start[0] + 1} Y={start[1] + 1}."
)
print_maze_with_coords(grid)
return
except Exception:
if tries >= 500:
raise ValueError("Не удалось сгенерировать лабиринт.")
def print_maze_file_interactive() -> None:
n = _read_int("Введите N (1..15): ", min_value=1, max_value=15)
grid = read_maze_from_file(n)
print("maze.txt:")
print_maze_with_coords(grid)
def solve_from_file_interactive() -> None:
n = _read_int("Введите N (1..15): ", min_value=1, max_value=15)
grid = read_maze_from_file(n)
print_maze_with_coords(grid)
x = _read_int("Введите строку (1..N): ", min_value=1, max_value=n)
y = _read_int("Введите колонку (1..N): ", min_value=1, max_value=n)
start = (x - 1, y - 1)
path = a_star_shortest_path(grid, start)
print("Путь:", path)
def main() -> None:
while True:
print()
print("Меню:")
print("1) Создать лабиринт")
print("2) Показать лабиринт")
print("3) Найти путь")
print("0) Выход")
try:
choice = input("Выберите пункт: ").strip()
except EOFError:
return
try:
if choice == "0":
return
if choice == "1":
generate_maze_file_interactive()
elif choice == "2":
print_maze_file_interactive()
elif choice == "3":
solve_from_file_interactive()
else:
print("Неизвестный пункт меню.")
except Exception as e:
print(f"Ошибка: {e}")
if __name__ == "__main__":
main()

View File

@@ -1,37 +1,75 @@
print("task: 6r\nВставка + и - между цифрами для получения числа N")
# task: Счастливый билет
# Дано шестизначное число и число N. Между цифрами можно вставлять +, -, ничего.
# Нужно вывести все выражения, равные N, либо сообщение об отсутствии решений.
import itertools
def generate(s, pos, expr, target, results):
if pos == len(s):
try:
if eval(expr) == target:
results.append(expr + "=" + str(target))
except:
pass
return
generate(s, pos + 1, expr + "+" + s[pos], target, results)
generate(s, pos + 1, expr + "-" + s[pos], target, results)
generate(s, pos + 1, expr + s[pos], target, results)
def generate_expressions(digits):
ops = ["+", "-", ""]
for comb in itertools.product(ops, repeat=5):
expr = digits[0]
for i in range(5):
expr += comb[i] + digits[i + 1]
yield expr
def safe_eval(expr):
try:
return eval(expr)
except:
return None
def solve(ticket, target):
results = []
digits = list(ticket)
for expr in generate_expressions(digits):
val = safe_eval(expr)
if val == target:
results.append(f"{expr}={target}")
return results
def is_valid_ticket(ticket):
return ticket.isdigit() and len(ticket) == 6 and int(ticket) > 0
def is_valid_target(target):
return target.isdigit() and 0 < int(target) < 10**9
while True:
print("\n1 - решить\n0 - выход")
try:
c = input("Выбор: ")
if c == "1":
s, target = input("Введите число и N: ").split()
target = int(target)
results = []
generate(s, 1, s[0], target, results)
with open("result.txt", "w") as f:
if results:
for r in results:
print(r)
f.write(r + "\n")
else:
print("Решение не существует")
f.write("Решение не существует")
elif c == "0":
break
except:
print("Ошибка ввода")
print("\nВыберите действие:")
print("1 - Ввести данные")
print("2 - Выход")
choice = input("Ваш выбор: ").strip()
if choice == "2":
print("Выход из программы.")
break
elif choice == "1":
ticket = input("Введите шестизначный номер билета: ").strip()
target = input("Введите число N (0 < N < 1e9): ").strip()
if not is_valid_ticket(ticket):
print("Ошибка: билет должен быть шестизначным натуральным числом.")
continue
if not is_valid_target(target):
print("Ошибка: N должно быть натуральным числом (0 < N < 1e9).")
continue
target = int(target)
solutions = solve(ticket, target)
if solutions:
print("\nНайденные решения:")
for s in solutions:
print(s)
else:
print("Решение не существует.")
else:
print("Некорректный выбор. Попробуйте снова.")