如何根据分数来查找和更新级别?

时间:2019-08-12 10:41:41

标签: ruby-on-rails algorithm data-structures

我正在创建一个像游戏一样的Rails应用程序。因此它具有点和层次。例如:要成为第一级,用户必须至少获得100分,而对于第二级,用户必须达到第二级,用户必须收集200分。等级差每10级改变一次,即每个等级之间的差总是10级之后改变。我的意思是,第一级和第二级之间的点差为100,而第11级和第12级之间的点差为150,依此类推。没有级别上限。

现在我的问题是,假设用户的总积分是3150,而最近更新为3155。找到当前水平并在需要时进行更新的最佳解决方案是什么?

我可以使用while循环并在其内部再次循环来获得解决方案,这将得出O(n ^ 2)的结果。我需要更好的东西。

我认为这段代码有效,但是我不确定这是否是解决问题的最佳方法

def get_level(points)
  diff = 100
  sum = 0
  level = -1
  current_level = 0

  while level.negative?
    10.times do |i|
      current_level += 1
      sum += diff

      if points > sum
        next
      elsif points <= sum
        level = current_level
        break
      end
    end  
    diff += 50
  end
  puts level
end

1 个答案:

答案 0 :(得分:1)

我写了一个get_points函数(应该不难)。然后基于它的get_level函数,有必要求解二次方程以找到high的值,然后计算low

如果您有任何疑问,请告诉我。

检查输出here

#!/usr/bin/env python3

import math


def get_points(level):
    high = (level + 1) // 10
    low = (level + 1) % 10
    high_point = 250 * high * high + 750 * high  # (3 + high) * high // 2 * 500
    low_point = (100 + 50 * high) * low
    return low_point + high_point


def get_level(points):
    # quadratic equation
    a = 250
    b = 750
    c = -points
    d = b * b - 4 * a * c
    x = (-b + math.sqrt(d)) / (2 * a)
    high = int(x)
    remainder = points - (250 * high * high + 750 * high)
    low = remainder // (100 + 50 * high)
    level = high * 10 + low
    return level


def main():
    for l in range(0, 40):
        print(f'{l:3d} {get_points(l - 1):5d}..{get_points(l) - 1}')

    for level, (l, r) in (
        (1, (100, 199)),
        (2, (200, 299)),
        (9, (900, 999)),
        (10, (1000, 1149)),
        (11, (1150, 1299)),
        (19, (2350, 2499)),
        (20, (2500, 2699)),
    ):
        for p in range(l, r + 1):  # for in [l, r]
            assert get_level(p) == level, f'{p} {l}'


if __name__ == '__main__':
    main()
  

为什么要设置a = 250且b = 750的值?你能给我解释一下吗?

让我们每10级写出一个点和点之间的差异:

lvl - pnt  (+delta)
 10 - 1000 (+1000 = +100 * 10)
 20 - 2500 (+1500 = +150 * 10)
 30 - 4500 (+2000 = +200 * 10)
 40 - 7000 (+2500 = +250 * 10)

除以500((10个级别* 50差异变化),并从2开始接受算术级数:

 10 - 2  (+2)
 20 - 5  (+3)
 30 - 9  (+4)
 40 - 14 (+5)

使用level = k * 10的{​​{3}}获得积分公式等于:

sum(x for x in 2..k+1) * 500 =
(2 + k + 1) * k / 2 * 500 = 
(3 + k) * k * 250 = 
250 * k * k + 750 * k

现在我们有points,并希望找到最大的high,使得point >= 250 * high^2 + 750 * high,即i。 e。 250 * high^2 + 750 * high - points <= 0。值a = 250为正,抛物线的分支向上。现在我们找到了arithmetic progression 250 * high^2 + 750 * high - points = 0的解决方案,并丢弃了真实部分(在python脚本中为high = int(x))。