在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.]
如果你有另一种产生相同结果的方法,那就更快了。
答案 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)]并将较小的一个作为实际输出。