找到最近三角形数字的最快方法?

时间:2014-04-27 04:47:47

标签: python

在python中,我需要一个取整数的函数,并将n的绝对值减去最近的triangle number到n。我现在的做法是生成一个最多为n的所有三角形数字的列表。 然后使用:

def closest(myList, myNumber):
    c = min(myList, key=lambda x:abs(x-myNumber))

找到最接近的三角形数字。

最终结果列表应如下所示:

[0, 0, 1 , 0 , 1 ,1 , 0 , 1, 2 , 1, 0 , 1, 2, 2, 1, 0, etc.]

如果你有另一种产生相同结果的方法,那就更快了。

5 个答案:

答案 0 :(得分:3)

一点点数学将带来更具分析性的解决方案:

from math import sqrt
def close_triangle2(n):
    m=int(0.5*(-1+sqrt(1+8*n))) #solve it for the explicit formula
    tan0=(m*m+m)/2              #the closest one is either this
    tan1=(m*m+3*m+2)/2          #or this
    if (n-tan0)>(tan1-n):
        return tan1-n
    else:
        return n-tan0

当数字很大时,它会比@perreal的循环版本略快一些:

In [87]:

%timeit close_triangle(111111111)
100000 loops, best of 3: 5 µs per loop
In [86]:

%timeit close_triangle2(111111111)
100000 loops, best of 3: 4.13 µs per loop

如果您想知道:

In [94]:

close_triangle2((30**10 * (30**10+1)) / 2 + 100)
Out[94]:
100L
In [95]:

close_triangle((30**10 * (30**10+1)) / 2 + 100)
Out[95]:
100L

In [102]:

%timeit close_triangle((30**10 * (30**10+1)) / 2 + 100)
10000 loops, best of 3: 17.9 µs per loop
In [103]:

%timeit close_triangle2((30**10 * (30**10+1)) / 2 + 100)
100000 loops, best of 3: 12 µs per loop

答案 1 :(得分:1)

可能不是最好的方法,但应该比你的方法更快:

def triangle_around(n):
    k = int((2*n)**0.5)
    p = (k**2 + k) / 2 
    while p < n:
        k, p = k + 1, p + k + 1 
    return (p - k, p)

def close_triangle(n):
    t = triangle_around(n)
    return min(t[1] - n, n - t[0])

print close_triangle(8)    # gives 2

答案 2 :(得分:1)

您可以利用 triangle-root 属性快速计算最接近数字的三角形数字,并从那里轻松计算您的值

from math import sqrt

def triangle_number(tnumber):
    '''
    returns the tnumberth triangle number (I.E 3 = 6)
    '''
    return (tnumber*(tnumber+1))/2

def triangle_root(number):
    '''
    returns the triangle root of a number (I.E 6 = 3)
    '''
    return (sqrt(8*number+1)-1)/2

def nearest_root(number):
    '''
    Calculates the nearest whole triangle root to a number (I.E. 5 = 3)
    '''
    t_root = triangle_root(number)
    return round(t_root)

def find_delta(number):
    '''
    Given a number, returns abs(n-nearest_triangle)
    '''
    return abs(number - triangle_number(nearest_root(number)))

当然,您可以将其浓缩为单一功能以提高效率,为了清晰起见,我只是将其分开。

答案 3 :(得分:1)

在我的解决方案中,我使用了这个事实 设K = sqrt(2 * N)  如果N是三角形数,那么它将是第K个三角形数 我们知道Kth三角形数将是K *(K + 1)/ 2

这是我的Python解决方案

from math import sqrt
from math import floor
def close_triangle(n):
m = floor(sqrt(2*n))
t1 = m*(m+1)/2       #next triangular number to n
m = m-1
t2 = m*(m+1)/2       #previous triangular number to n
diff1 = t1-n
diff2 = n - t2
if diff1 < diff2 :
  return t1
else:
  return t2
print "Nearest trianguler number";
print close_triangle(13)

答案 4 :(得分:0)

我有一个解决方案,不需要先计算每个三角形数字,但我不确定它是否最好。

由于triange数的公式是

    A(n) = n*(n-1)/2       (n is integer)

对于输入x,它应该在A(n)和A(n + 1)

的中间
    A(n) <= x <= A(n+1)

对于A(n),我们有:

    n * (n - 1) / 2 <= x
    (n - 1)^2 < n * (n-1) <= 2*x
    n < sqrt(2*x) + 1

对于A(n + 1),我们有:

    (n + 1)^2 > (n + 1) * n >= 2*x
    n > sqrt(2*x) - 1

现在,如果我们输入数字x,我们可以快速找到在[A(n),A(n + 1)]中生成x的n,那么我们只需要计算[abs(A(n)]的距离 - x),abs(A(n + 1) - x)]并将较小的一个作为实际输出。