使用加法、减法和减半计算三角根

2024-03-18

特定游戏的规则是角色的力量与角色的力量成正比。三角根 https://math.stackexchange.com/q/698961/93170角色的经历。例如,15-20经验获得5力量,21-27经验获得6力量,28-35经验获得7力量等等。据了解,有些玩家的经验达到了数千亿。

我试图在只有三个算术指令的 8 位机器上实现这个游戏:加法、减法和除以 2。例如,要将一个数字乘以 4,程序会将其与自身相加两次。一般乘法要慢得多;我已经编写了一个软件子例程来使用四分之一方桌来完成此操作。

我曾考虑过计算三角根T(p)通过二分搜索 https://en.wikipedia.org/wiki/Bisection_method用于从上方和下方限定经验数的连续三角形数。我的计划是使用重复身份T(2*p)直到它超过经验,然后将其用作二分搜索的上限。但我很难找到一个身份T((x+y)/2)在不使用任何一个的二分法中x*y or (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

进行二分搜索,但确保y - x总是 2 的幂。 (这不会增加渐近运行时间。)然后T((x + y) / 2) = T(x) + T(h) + x * h, where h是二的幂,所以x * h可以通过平移来计算。

这是一个 Python 概念证明(仓促编写,或多或少未优化,但避免了昂贵的操作)。

def tri(n):
    return ((n * (n + 1)) >> 1)

def triroot(t):
    y = 1
    ty = 1

    # Find a starting point for bisection search by doubling y using
    # the identity T(2*y) = 4*T(y) - y. Stop when T(y) exceeds t.
    # At the end, x = 2*y, tx = T(x), and ty = T(y).
    while (ty <= t):
        assert (ty == tri(y))
        tx = ty
        ty += ty
        ty += ty
        ty -= y
        x = y
        y += y

    # Now do bisection search on the interval [x .. x + h),
    # using these identities:
    # T(x + h) = T(x) + T(h) + x*h
    # T(h/2) = (T(h) + h/2)/4
    th = tx
    h = x
    x_times_h = ((tx + tx) - x)
    while True:
        assert (tx == tri(x))
        assert (x_times_h == (x * h))

        # Divide h by 2
        h >>= 1
        x_times_h >>= 1
        if (not h):
            break
        th += h
        th >>= 1
        th >>= 1

        # Calculate the midpoint of the search interval
        tz = ((tx + th) + x_times_h)
        z = (x + h)
        assert (tz == tri(z))

        # If the midpoint is below the target, move the lower bound
        # of the search interval up to the midpoint
        if (t >= tz):
            tx = tz
            x = z
            x_times_h += ((th + th) - h)
    return x
for q in range(1, 100):
    p = triroot(q)
    assert (tri(p) <= q < tri((p + 1)))
    print(q, p)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用加法、减法和减半计算三角根 的相关文章

  • 另一个生命游戏问题(无限网格)?

    我一直在玩 Conway 的生命游戏 最近发现了一些令人惊讶的快速实现 例如 Hashlife 和 Golly 在这里下载Golly http golly sourceforge net http golly sourceforge net
  • 如何反向for循环?

    我正在制作一个水模拟程序 我需要它通过 y x 进行 for 循环 但我需要它先检查最底部的 y 然后向上检查 这是我的等级 lvl 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 我需要
  • 用于将分层平面数据(带 ParentID)转换为带缩进级别的排序平面列表的算法

    我有以下结构 MyClass guid ID guid ParentID string Name 我想创建一个数组 其中包含按层次结构中应显示的顺序排列的元素 例如 根据它们的 左 值 以及将 guid 映射到缩进级别的散列 例如 ID N
  • 棒材切割 - 动态规划

    问题陈述 棒材切割问题如下 给定一根长度为n英寸和价格表Pi for i 1 2 3 n 确定最大收益Rn可以通过切割棒并出售碎片来获得 请注意 如果价格Pn对于一根长度的杆n足够大 最佳解决方案可能根本不需要切割 考虑以下情况 n 4 图
  • 在地图元素上使用 for_each

    我有一个映射 我想在其中对每个数据类型对象成员函数执行调用 我还知道如何在任何序列上执行此操作 但是是否可以在关联容器上执行此操作 我能找到的最接近的答案是 Boost Bind 访问 std for each 中的 std map 元素
  • 埃拉托色尼筛法的 Java 实现可以超过 n = 2^32?

    目前我有这个质数生成器 其限制为 n Sieve public class Main public static void main String args long N 2000000000 initially assume all in
  • ASM 中从小端到大端的快速转换

    我在 C 中有一个 uint 类型数组 在检查程序是否在小端机器上运行后 我想将数据转换为大端类型 因为数据量可能会变得非常大 但总是均匀的 所以我想考虑将两个 uint 类型作为 ulong 类型 以获得更好的性能并在 ASM 中对其进行
  • 什么是日历队列?

    我正在致力于构建一个离散事件模拟器 维基百科提到有几种通用优先级队列非常适合在 DES 中使用 具体来说 它提到日历队列是一个很好的结构 我找到了一份 pdf 1988 年的 其中提到了日历队列 但在大多数情况下我找不到关于它们的任何其他内
  • 如何使用 Span 和 stackalloc 创建临时小列表

    我正在阅读一些用 C 编写的代码的描述 这些代码由于在堆栈上而不是堆上分配临时数组以在非常热的循环中使用而提高了速度 它被描述为类似于 SBO 优化 有问题的对象类似于List
  • 将 2:1 等距柱状全景图转换为立方体贴图

    我目前正在为网站开发一个简单的 3D 全景查看器 出于移动性能的原因 我使用 Three jsCSS 3 渲染器 https github com mrdoob three js blob master examples css3d pan
  • 为什么 C# 默认不使用算术溢出检查? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么语言默认情况下不会引发整数溢出错误 https stackoverflow com questions 103654 why dont languages raise errors on int
  • Java 服务器和浏览器客户端之间乐观对象复制的解决方案?

    我正在构建一个系统 多个用户需要同时创建 查看和修改一组对象 该系统计划在 Java 服务器和现代浏览器客户端上运行 我可以选择哪些 它需要在网络和服务器中断时具有鲁棒性 用户界面不得阻止修改 修改需要存储在本地并在连接恢复时发布 在正常操
  • 无限循环:确定并打破无限循环

    你如何判断一个循环是无限循环并且会跳出它 有没有人有算法或者可以帮助我解决这个问题 Thanks 没有通用的算法可以确定程序是否处于无限循环中图灵完备 http en wikipedia org wiki Turing completene
  • 我怎样才能优化这个vba循环代码?

    嗨 我写了这段代码 但这段代码非常慢 我该如何优化这段代码 Private Sub printItem r lastCol objStream FirstCol 1 Dim strFirst As String strFirst CStr
  • 约束优化 R:另一个例子

    我正在尝试在 R 中执行约束优化 我已经查看了这些帖子和其他一些帖子 R 中的约束优化 https stackoverflow com questions 5436630 constrained optimization in r R 中的
  • 递归分层父子

    我有一个来自数据库的项目集合 该数据库具有parentid值或空 这是我的班级设计 public class Item public int id get set public string Name get set public int
  • 如何编写一个简单的版本控制系统?

    我想做一个简单的版本控制系统 但我不知道如何构建我的数据和代码 这是一个简短的例子 用户登录 User has two options when uploading a file 提交新文件 提交文件的新版本 用户应该能够看到树 版本不同
  • 向量数学,在两个向量之间的平面上查找坐标

    我正在尝试沿着样条线生成 3d 管 我有样条线的坐标 x1 y1 z1 x2 y2 z2 等 您可以在黄色插图中看到 在这些点上 我需要生成圆圈 其顶点将在稍后的体育场连接 这些圆需要垂直于样条线两条线段的 角 才能形成正确的管 请注意 出
  • 任意旋转中两条抛物线相交的代码或公式

    我正在研究一个几何问题 需要找到任何旋转中两个抛物线弧的交点 我能够通过旋转平面使弧与轴对齐来相交直线和抛物线弧 但两条抛物线不能同时与轴对齐 我正在努力推导公 式 但我想知道是否有可用的资源 我首先定义没有旋转的二维抛物线弧的方程 x t
  • 如何使用 C 中的 Banker's Rounding 将 double 舍入为 int

    我想编写一个函数 使用银行家的舍入方法将双精度数舍入为整数 将一半舍入为偶数 http en wikipedia org wiki Rounding Round half to even http en wikipedia org wiki

随机推荐