2025, Nov 03 21:02

Равные суммы четвертых степеней в Python: надежный поиск и проверка оснований

Как находить равные суммы четвертых степеней в Python: тождество по k, n, x, строгая проверка целочисленных оснований и допуск для ошибок вычислений чисел.

Найти равные суммы четвертых степеней — задача небанальная. Компактное тождество сводит обычный поиск по четырем переменным к трем целым k, n, x и по ним строит четыре выражения, четвертые степени которых удовлетворяют равенству в духе задачи о такси. Подвох практический: наивные вычисления с плавающей точкой охотно выдают множество почти совпадений, а без явных проверок вы будете пропускать нецелые основания. Ниже — краткий разбор, как организовать надежный поиск на Python, который возвращает тройки (k, n, x) только тогда, когда все четыре основания целые и равенство выполняется в пределах жесткого допуска.

Подготовка: цель поиска и базовый вариант

Тождество дает четыре выражения, зависящие от n, k, x. Цель — найти положительные целые n, k, x такие, чтобы каждое из этих четырех выражений было точной четвертой степенью, а сумма слева равнялась сумме справа. Например, при n = 24, k = 74, x = 300783360 тождество приводит к 158^4 + 59^4 = 134^4 + 133^4, где каждый четвертый корень — ровно положительное целое. Именно такие попадания и должен находить код.

Прямолинейная реализация вычисляет обе стороны численно, но не контролирует целочисленность каждого основания. Поэтому она возвращает множество ложных срабатываний. Ниже — показательный базовый вариант, который демонстрирует это поведение.

import math
# константы для кубического корня
r13 = (1.0 / 3.0) ** (1.0 / 3.0)
r13_2 = (1.0 / 3.0) ** (2.0 / 3.0)
def root3(val):
    if val >= 0:
        return val ** (1.0 / 3.0)
    else:
        return -(-val) ** (1.0 / 3.0)
def core(term, X):
    return (
        3.0 * term ** 3
        - 3.0 * (term ** 4 - X) / term
        + math.sqrt((1.0 / 3.0) * term ** 8 + 9.0 * X ** 2) / term
    )
def sum_left(N, K, X):
    Rn = root3(core(N, X))
    Rk = root3(core(K, X))
    A = (-0.5 * (r13 * N) ** 2 / Rn + 0.5 * N + 0.5 * r13 * Rn) ** 4
    B = (-0.5 * r13_2 * K ** 2 / Rk - 0.5 * K + 0.5 * r13 * Rk) ** 4
    return A + B
def sum_right(N, K, X):
    Rn = root3(core(N, X))
    Rk = root3(core(K, X))
    C = (-0.5 * (r13 * N) ** 2 / Rn - 0.5 * N + 0.5 * r13 * Rn) ** 4
    D = (-0.5 * r13_2 * K ** 2 / Rk + 0.5 * K + 0.5 * r13 * Rk) ** 4
    return C + D

Эта версия может показывать очень малую разницу между левой и правой частями, но не гарантирует, что сами четыре основания — целые. В этом и заключалась основная проблема.

Что именно идет не так

Проблем здесь две, и они связаны. Во‑первых, если не извлекать и не проверять основания до возведения в четвертую степень, нельзя требовать, чтобы каждый член был идеальной четвертой степенью. Во‑вторых, даже при корректном алгебраическом тождестве вычисления с плавающей точкой вносят крошечные погрешности; если сравнивать только суммы, вы получите почти нулевую ошибку и для нецелых оснований, что неприемлемо, когда нужны точные целые четвертые степени.

Решение: явно проверять все четыре основания

Практическое средство простое и действенное. Явно вычисляйте четыре основания слева и справа, проверяйте, что каждое численно близко к целому в пределах строгого допуска, и лишь затем сравнивайте стороны. Ключевой момент — возвращать основания вместе с суммами и валидировать их. Если нужны только положительные основания, добавьте и это ограничение.

import math
# константы для кубического корня
r13 = (1.0 / 3.0) ** (1.0 / 3.0)
r13_2 = (1.0 / 3.0) ** (2.0 / 3.0)
def root3(val):
    if val >= 0:
        return val ** (1.0 / 3.0)
    else:
        return -(-val) ** (1.0 / 3.0)
def core(term, X):
    return (
        3.0 * term ** 3
        - 3.0 * (term ** 4 - X) / term
        + math.sqrt((1.0 / 3.0) * term ** 8 + 9.0 * X ** 2) / term
    )
def left_terms(N, K, X):
    Rn = root3(core(N, X))
    Rk = root3(core(K, X))
    u1 = (-0.5 * r13_2 * N ** 2 / Rn + 0.5 * N + 0.5 * r13 * Rn)
    u2 = (-0.5 * r13_2 * K ** 2 / Rk - 0.5 * K + 0.5 * r13 * Rk)
    A = u1 ** 4
    B = u2 ** 4
    return A + B, u1, u2
def right_terms(N, K, X):
    Rn = root3(core(N, X))
    Rk = root3(core(K, X))
    u3 = (-0.5 * r13_2 * N ** 2 / Rn - 0.5 * N + 0.5 * r13 * Rn)
    u4 = (-0.5 * r13_2 * K ** 2 / Rk + 0.5 * K + 0.5 * r13 * Rk)
    C = u3 ** 4
    D = u4 ** 4
    return C + D, u3, u4
def intlike(val, tol=1e-12):
    return abs(val - round(val)) < tol
# Пример целенаправленного поиска при фиксированных (N, K)
count = 0
limit = 1000
EPS = 1e-6
for N in range(24, 25):
    for K in range(74, 75):
        for X in range(1, 300790000):
            try:
                left_sum, a1, a2 = left_terms(N, K, X)
                right_sum, b1, b2 = right_terms(N, K, X)
                err = abs(left_sum - right_sum)
                if err < EPS:
                    if intlike(a1) and intlike(a2) and intlike(b1) and intlike(b2):
                        # Если нужны только положительные основания, добавьте: and a1 > 0 and a2 > 0 and b1 > 0 and b2 > 0
                        count += 1
                        print(
                            f"hit: n={N} k={K} x={X} error={err:.2e} "
                            f"bases=({a1}, {a2}, {b1}, {b2})"
                        )
                        if count >= limit:
                            raise StopIteration
            except StopIteration:
                raise
            except Exception:
                continue

Это обеспечивает ровно то, что требуется: каждое из четырех оснований должно иметь целочисленное значение, а равенство левой и правой частей — укладываться в строгий допуск. При n = 24 и k = 74 первое попадание появляется при x = 5374176 с основаниями (49, 25, −25, 49). Если нужны все четыре положительные, добавьте соответствующее условие и продолжайте. Тот же проход также находит чистый пример n = 24, k = 74, x = 300783360, дающий 158^4 + 59^4 = 134^4 + 133^4 с целыми четвертыми корнями во всех терминах.

Почему допуск все еще необходим

Даже при математически корректном тождестве вычисление вложенных радикалов и кубических корней в плавающей точке накапливает малые ошибки. Поэтому сравнение обеих сторон с допуском обязательно. Проверка целочисленности оснований — тест на близость к ближайшему целому — отделяет точный алгебраический замысел от численного шума. Вместе эти два условия убирают ложные срабатывания и сохраняют валидные решения.

Почему это важно при поиске равных четвертых степеней

Равенства сумм двух четвертых степеней обычно требуют перебора четырех целых. Здесь же конструкция фактически переносит поиск в трехпараметрическое пространство (k, n, x), что делает грубый перебор более посильным. Но реализация должна быть дисциплинированной: без проверки целочисленности каждого основания большая часть времени уйдет на почти‑равенства, которые не являются идеальными четвертыми степенями. Дополнительные проверки оснований и порог по допуску резко очищают набор кандидатов.

В заключение

Если нужно находить целые тройки (k, n, x), при которых получающиеся четыре члена — идеальные четвертые степени и тождество выполняется, явно вычисляйте основания, подтверждайте, что каждое целочисленно в пределах строгого порога, и только потом сравнивайте стороны с малым допуском. Если требуется также, чтобы все четыре основания были положительными, добавьте это условие. Можно сужать или расширять диапазоны, фиксировать n и k и сканировать x, как показано выше; главное — проверки на целочисленность и допуск вместе отделяют истинные структурные попадания от «похожих» численных результатов.

Статья основана на вопросе на StackOverflow от Agbanwa Jamal и ответе smallio.