Спасибо за формулу. Теперь реализовал это в коде на Python в Colab. В дороге можно быстро производить расчет.
import math
# --- Существующие функции ---
def рассчитать_данные_ячейки(x):
"""
Рассчитывает "Ячеек от начала цикла" и "Номер цикла" для заданного числа X.
Эти расчеты основаны на поиске положения числа X в квадратной спирали,
используя его квадратный корень и связь с нечетными квадратами и циклами спирали.
Формула для "Ячеек от начала цикла":
Ячеек от начала цикла = X - ( (ОкругленноеНечетное(КОРЕНЬ(X)))^2 - 8 * НомерЦикла + 1 )
Где:
- X: Входное число, для которого производится расчет.
- ОкругленноеНечетное(Y): Функция, которая округляет Y до ближайшего нечетного целого числа
(вверх, если Y не целое или целое четное).
- НомерЦикла (M): Определяется из КОРЕНЬ(X) и K по следующей логике:
- K: Ближайшее нечетное целое число, меньшее или равное ЦЕЛОЕ(КОРЕНЬ(X)).
- Если КОРЕНЬ(X) точно равен K, то НомерЦикла = ЦелаяЧасть(K/2) (округление K/2 вниз до ближайшего целого).
- В противном случае (если КОРЕНЬ(X) не равно K), то НомерЦикла = ОкруглениеВверх(K/2) (округление K/2 вверх до ближайшего целого).
Пример: Для X=144, КОРЕНЬ(144)=12. K=11. НомерЦикла = ОкруглениеВверх(11/2)=6.
ОкругленноеНечетное(12) = 13.
Ячеек от начала цикла = 144 - (13^2 - 8*6 + 1) = 144 - (169 - 48 + 1) = 144 - 122 = 22.
"""
s = math.sqrt(x)
i = math.floor(s)
if i % 2 == 0: # Если I четное
k = i - 1
else: # Если I нечетное
k = i
if abs(s - k) < 1e-9: # Используем небольшую погрешность для сравнения чисел с плавающей точкой
m = math.floor(k / 2) # Соответствует ЦелаяЧасть(K/2)
else:
m = math.ceil(k / 2) # Соответствует ОкруглениеВверх(K/2)
номер_цикла = m
# Уточненная логика ОкругленноеНечетное(Y):
# Округляет число до ближайшего нечетного целого.
# Если число уже целое нечетное, то оно же.
# Если число целое четное, то оно +1. Если дробное, то округляет вверх до ближайшего нечётного.
if s % 1 == 0 and s % 2 != 0: # Если S целое и нечетное
s_нечетное_округленное_фактическое = int(s)
elif s % 1 == 0 and s % 2 == 0: # Если S целое и четное
s_нечетное_округленное_фактическое = int(s) + 1
else: # Если S дробное
s_нечетное_округленное_фактическое = math.ceil(s)
if s_нечетное_округленное_фактическое % 2 == 0:
s_нечетное_округленное_фактическое += 1
ячеек_от_начала_цикла = x - ((s_нечетное_округленное_фактическое**2) - 8 * номер_цикла + 1)
return ячеек_от_начала_цикла, номер_цикла
def рассчитать_градус(ячеек_от_начала_цикла, номер_цикла):
"""
Рассчитывает градус круга для заданных "Ячеек от начала цикла" и "Номер цикла".
Соответствует формуле Градуса.
"""
A = ячеек_от_начала_цикла
N = номер_цикла
Q = math.floor(A / N)
R = A - Q * N + 1
if Q == 0 and N - A == 1:
return 0.0
elif Q == 0 and N > A:
терм_атан = math.degrees(math.atan((1 - R / N)))
градус = 360 - abs((45 * Q) - терм_атан)
return градус
else:
if Q % 2 == 0: # Если Q четное
терм_атан = math.degrees(math.atan((1 - R / N)))
градус = abs((45 * Q) - терм_атан)
return градус
else: # Если Q нечетное
терм_атан = math.degrees(math.atan(R / N))
градус = abs(45 * (Q - 1)) + терм_атан
return градус
# --- Новая функция для "Количество ячеек от нуля круга" ---
def рассчитать_ячейки_от_нуля_круга(x_вход):
"""
Рассчитывает "Количество ячеек от нуля круга" по алгоритму,
включающему корректировку на "предыдущий слой" при отрицательной разнице.
"""
# Исходный Шаг 1 и Шаг 2 (потенциально временные)
# Находим ближайший sqrt() и определяем начальное X (сторону квадрата)
s = math.sqrt(x_вход)
# Округляем до ближайшего целого числа вверх.
округленное_s_вверх = math.ceil(s)
# Находим ближайшее нечетное число, которое больше или равно округленное_s_вверх.
начальная_длина_стороны_x = округленное_s_вверх
if начальная_длина_стороны_x % 2 == 0: # Если четное, переходим к следующему нечетному числу
начальная_длина_стороны_x += 1
текущая_длина_стороны_x = начальная_длина_стороны_x
while True: # Будем повторять до тех пор, пока разница не станет >= 0
# Размер "Цикла" для текущей длины стороны: (сторона - 1) * 4
размер_цикла = (текущая_длина_стороны_x - 1) * 4
# "Номер Цикла" для текущей длины стороны: (Размер Цикла) / 8
номер_цикла_для_расчета = размер_цикла // 8
# Число на 0 градусов для текущей длины стороны: (сторона - 2)^2 + НомерЦиклаДляРасчета
число_на_0_градусов = (текущая_длина_стороны_x - 2)**2 + номер_цикла_для_расчета
# Разница между входным числом и числом на 0 градусов текущего цикла
разница = x_вход - число_на_0_градусов
if разница >= 0:
# Если разница >= 0, принимаем этот ответ и выходим из цикла
return разница
else:
# Если разница < 0, корректировка: переходим к предыдущему слою/циклу.
# Для этого уменьшаем текущую_длину_стороны_x на 2.
текущая_длина_стороны_x -= 2
# Проверка на случай, если X_вход слишком мало или алгоритм не сходится.
if текущая_длина_стороны_x < 1:
return "Ошибка: Не удалось найти положительную разницу. Проверьте входное число или логику."
# --- Основное выполнение программы ---
if __name__ == "__main__":
while True:
try:
ввод_x_строка = input("Введите число X (для выхода введите 'q'): ")
if ввод_x_строка.lower() == 'q':
break
x = float(ввод_x_строка)
if x < 0:
print("Число X должно быть неотрицательным.")
continue
# Рассчитываем значения с использованием первой группы формул
ячеек_от_начала_цикла, номер_цикла = рассчитать_данные_ячейки(x)
градус_круга = рассчитать_градус(ячеек_от_начала_цикла, номер_цикла)
# Рассчитываем "Количество ячеек от нуля круга" по новому алгоритму
ячеек_от_нуля_круга = рассчитать_ячейки_от_нуля_круга(x)
print(f"\nДля числа X = {x}:")
print(f" Ячеек от начала цикла: {ячеек_от_начала_цикла}")
print(f" Номер цикла: {номер_цикла}")
print(f" Градус круга: {градус_круга:.2f}°")
print(f" Количество ячеек от нуля круга: {ячеек_от_нуля_круга}") # Может быть строкой при ошибке
print("-" * 30)
except ValueError:
print("Ошибка: Введите корректное число.")
except Exception as e:
print(f"Произошла непредвиденная ошибка: {e}")