Загрузка данных


from fractions import Fraction
import os

# ---------- input.txt ----------
if not os.path.exists("input.txt"):
    with open("input.txt", "w") as f:
        f.write("1 1 2 1 7\n2 2 2 -1 3\n3 1 -1 4 0\n4\n")

# ---------- вспомогательное ----------
def fmt(x):
    return str(x.numerator) if x.denominator == 1 else f"{x.numerator}/{x.denominator}"

def read_input(path):
    rows = []
    for line in open(path):
        t = line.split()
        if len(t) < 2:              # пропускаем одиночные числа вроде "4"
            continue
        rows.append([Fraction(v.replace(",", ".")) for v in t])
    n = len(rows)
    # если первый столбец - номера строк 1..n, убираем его
    if all(len(r) == n + 2 for r in rows) and all(r[0] == i + 1 for i, r in enumerate(rows)):
        rows = [r[1:] for r in rows]
    A = [r[:-1] for r in rows]      # матрица коэффициентов
    B = [r[-1] for r in rows]       # свободные члены
    return A, B

def show_system(A, B):
    for row, b in zip(A, B):
        s = ""
        for j, a in enumerate(row):
            if a == 0:
                continue
            c = abs(a)
            term = ("" if c == 1 else fmt(c)) + f"x{j+1}"
            if s:
                s += (" - " if a < 0 else " + ") + term
            else:
                s += ("-" if a < 0 else "") + term
        print(f"  {s or '0'} = {fmt(b)}")

def show(M, aug=False):
    w = max(len(fmt(v)) for r in M for v in r)
    for r in M:
        if aug:
            left = "  ".join(fmt(v).rjust(w) for v in r[:-1])
            print(f"  │ {left} │ {fmt(r[-1]).rjust(w)} │")
        else:
            print("  │ " + "  ".join(fmt(v).rjust(w) for v in r) + " │")

def det(M):
    M = [r[:] for r in M]
    n, d = len(M), Fraction(1)
    for i in range(n):
        p = next((r for r in range(i, n) if M[r][i] != 0), None)
        if p is None:
            return Fraction(0)
        if p != i:
            M[i], M[p] = M[p], M[i]
            d = -d
        d *= M[i][i]
        for r in range(i + 1, n):
            k = M[r][i] / M[i][i]
            M[r] = [a - k * b for a, b in zip(M[r], M[i])]
    return d

# ---------- Крамер ----------
def cramer(A, B):
    n = len(B)
    D = det(A)
    print("Матрица A:")
    show(A)
    print(f"\nΔ = {fmt(D)}")
    if D == 0:
        print("Δ = 0 → метод Крамера не применим")
        return None
    x = []
    for i in range(n):
        Ai = [r[:] for r in A]
        for r in range(n):
            Ai[r][i] = B[r]         # заменяем i-й столбец на B
        Di = det(Ai)
        print(f"\nМатрица A{i+1} (столбец {i+1} заменён на B):")
        show(Ai)
        print(f"Δ{i+1} = {fmt(Di)}   →   x{i+1} = Δ{i+1}/Δ = {fmt(Di / D)}")
        x.append(Di / D)
    return x

# ---------- Гаусс ----------
def gauss(A, B):
    n = len(B)
    M = [A[i][:] + [B[i]] for i in range(n)]
    print("Расширенная матрица [A | B]:")
    show(M, aug=True)
    # прямой ход
    for i in range(n):
        p = next((r for r in range(i, n) if M[r][i] != 0), None)
        if p is None:
            print("\nНет ведущего элемента → единственного решения нет")
            return None
        if p != i:
            M[i], M[p] = M[p], M[i]
            print(f"\nШаг {i+1}: R{i+1} ↔ R{p+1}")
            show(M, aug=True)
        piv = M[i][i]
        if piv != 1:
            M[i] = [v / piv for v in M[i]]
            print(f"\nШаг {i+1}: R{i+1} = R{i+1} / {fmt(piv)}")
            show(M, aug=True)
        for j in range(i + 1, n):
            k = M[j][i]
            if k != 0:
                M[j] = [a - k * b for a, b in zip(M[j], M[i])]
                print(f"\nШаг {i+1}: R{j+1} = R{j+1} - ({fmt(k)})·R{i+1}")
                show(M, aug=True)
    # обратный ход
    print("\nОбратный ход:")
    x = [Fraction(0)] * n
    for i in range(n - 1, -1, -1):
        x[i] = M[i][-1] - sum(M[i][j] * x[j] for j in range(i + 1, n))
        print(f"  x{i+1} = {fmt(x[i])}")
    return x

# ---------- запуск ----------
A, B = read_input("input.txt")

print("=" * 40)
print("СИСТЕМА:")
show_system(A, B)

print("\n" + "=" * 40)
print("МЕТОД КРАМЕРА")
print("=" * 40)
xc = cramer(A, B)

print("\n" + "=" * 40)
print("МЕТОД ГАУССА")
print("=" * 40)
xg = gauss(A, B)

print("\n" + "=" * 40)
print("ОТВЕТ:")
if xg:
    for i, v in enumerate(xg):
        print(f"  x{i+1} = {fmt(v)}")
    ok = all(sum(a * v for a, v in zip(row, xg)) == b for row, b in zip(A, B))
    print("Проверка подстановкой:", "✓ верно" if ok else "✗ ошибка")