Согласно правилу конкретной игры, сила персонажа пропорциональна треугольному корню опыта персонажа. Например, 15-20 опыта дают 5 силы, 21-27 опыта дают 6 силы, 28-35 опыта дают 7 силы и т. д. Известно, что некоторые игроки достигли опыта в сотни миллиардов.
Я пытаюсь реализовать эту игру на 8-битной машине, которая имеет только три арифметических инструкции: сложение, вычитание и деление на 2. Например, чтобы умножить число на 4, программа дважды сложит его сама с собой. Общее умножение намного медленнее; Я написал программную подпрограмму, чтобы сделать это, используя таблицу в четверть квадрата.
Я рассматривал возможность вычисления треугольного корня T(p)
с помощью поиска пополам для последовательных треугольных чисел, ограничивающих число опыта. сверху и снизу. Мой план состоял в том, чтобы использовать повторяющуюся идентичность для T(2*p)
до тех пор, пока она не превысит опыт, а затем использовать ее в качестве верхней границы для поиска пополам. Но у меня возникли проблемы с поиском идентификатора для T((x+y)/2)
в делении пополам, в котором не используются ни x*y
, ни (x+y)^2
.
Существует ли эффективный алгоритм для вычисления треугольного корня числа с помощью простого сложения, вычитания и деления пополам? Или мне придется выполнять O(log n) умножений, по одному для вычисления каждой средней точки в поиске пополам? Или было бы лучше рассмотреть возможность деления в длину, чтобы использовать метод Ньютона?
Определение T(x)
:
T(x) = (n * (n + 1))/2
Тождества, которые я получил:
T(2*x) = 4*T(x) - x
# e.g. T(5) = 15, T(10) = 4*15 - 5 = 55
T(x/2) = (T(x) + x/2)/4
# e.g. T(10) = 55, T(5) = (55 + 5)/4 = 15
T(x + y) = T(x) + T(y) + x*y
# e.g. T(3) = 6, T(7) = 28, T(10) = 6 + 28 + 21 = 55
T((x + y)/2) = (T(x) + T(y) + x*y + (x + y)/2)/4
# e.g. T(3) = 6, T(7) = 28, T(5) = (6 + 28 + 21 + 10/2)/4 = 15