优化Julia单行代码求解欧拉问题12的性能方案
欧拉问题12的Julia代码优化方案
原代码的性能瓶颈
你的代码慢的核心原因有两个:
- 因数计算效率极低:遍历从1到三角形数
s的所有数统计因数,时间复杂度为O(s),随着s增大,循环耗时呈指数级上升; - 未利用三角形数的数学性质:三角形数
T(n) = n*(n+1)/2中,n和n+1是互质的,可拆分因数个数的计算,无需直接处理大数。
优化步骤与代码
1. 高效的因数个数计算函数
用质因数分解法计算因数个数,时间复杂度降至O(√n),比原方法快数个数量级:
function count_divisors(n) count = 1 # 处理2的幂次因子 while n % 2 == 0 count += 1 n ÷= 2 end # 处理所有奇数因子 i = 3 while i*i <= n current_count = 1 while n % i == 0 current_count += 1 n ÷= i end count *= current_count i += 2 end # 若剩余n是大于2的质数,额外乘2 n > 2 && (count *= 2) return count end
2. 利用互质性质拆分计算
由于n和n+1互质,三角形数的因数个数可拆分为两个互质数的因数个数乘积:
- 当
n为偶数时:T(n) = (n/2) * (n+1),因数个数 =count_divisors(n÷2) * count_divisors(n+1) - 当
n为奇数时:T(n) = n * ((n+1)/2),因数个数 =count_divisors(n) * count_divisors((n+1)÷2)
3. 单行风格的求解代码
结合上述优化,写成符合你习惯的单行求解形式:
count_divisors(n) = let c=1, m=n; while m%2==0 c+=1; m÷=2 end; i=3; while i*i<=m cc=1; while m%i==0 cc+=1; m÷=i end; c*=cc; i+=2 end; m>2 ? c*2 : c end first(n*(n+1)÷2 for n in Iterators.countfrom() if count_divisors(isodd(n) ? n : n÷2) * count_divisors(isodd(n) ? (n+1)÷2 : n+1) > 500)
效果对比
原代码耗时约3分钟,优化后的代码在普通机器上仅需几毫秒即可得到结果,性能提升极其显著。
内容的提问来源于stack exchange,提问作者René
相关产品推荐
相关产品推荐

