Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The code shown below avoids several problems that are present in previously-presented code.</p> <p>A problem in the original post is counting divisors by testing all numbers less than the number <code>t</code> being processed. Various possible speedups exist: Don't test the numbers between <code>(t+2)/2</code> and <code>t-1</code>, because none of them can divide <code>t</code>. That could be extended (for example, numbers between <code>(t+3)/3</code> and <code>(t-1)/2</code> don't need to be tested) but returns diminish rapidly. A more important speedup is to use a multiplicative form of the <a href="https://en.wikipedia.org/wiki/Divisor_function" rel="nofollow">divisor function</a>; for example, if a number <code>t</code> equals <code>pᵃ·qᵇ·rᶜ</code> with <code>p, q, r</code> prime, then <code>σ₀(t) = τ(t) = (a+1)·(b+1)·(c+1)</code>. (The divisor-counting function σ₀ (sigma zero) often is indicated by τ (tau) instead of σ₀.)</p> <p>A problem in another answer is factoring <code>(i*(i+1)/2)</code> or <code>n*(n+1)/2</code> at each step. It is faster to just factor <code>i+1</code> or <code>n+1</code> at each step, and remember the factors from the previous step. This cuts execution time by a factor of at least 2.</p> <p>The code below computes <code>τ(k·(k+1)/2)</code> by <code>τ(k)·τ(k+1)·e/(e+1))</code>, where <code>e</code> represents the exponent of 2 in the product <code>τ(k)·τ(k+1)</code>. That is, because no prime factor of <code>k</code> can be a prime factor of <code>k+1</code>, and vice versa, <code>τ(k·(k+1)) = τ(k)·τ(k+1)</code>; and <code>τ(k·(k+1)/2)</code> is smaller than <code>τ(k·(k+1))</code> by the ratio <code>e/(e+1)</code>. </p> <p>The attached program runs in about 0.14 seconds on my older computer, when invoked by <code>findHiTau(120)</code>. The parameter to <code>findHiTau</code> is an upper limit on size of primes in the program's <code>oddprimes</code> table, and is the square root of the highest value of <code>k</code> tested; so triangular numbers as large as about <code>k⁴/2</code> will be processed.</p> <pre><code># Returns divisor count for integer v and power of 2 in v def tau(v): p2 = 0 while v%2 == 0: v, p2 = v/2, p2+1 t = p2+1 for p in oddprimes: if v%p == 0: e = 1 while v%p == 0: v, e = v/p, e+1 t *= e if p*p &gt; v: break if v&gt;1: # Rest of v is a prime t *= 2 return (t, p2) def findHiTau(primeLim): # Show record-high values of tau(k*(k+1)/2) up to k=m # Make array of small odd primes (expression is ok at least to 100K) oddprimes = [3,5,7,11,13]+[x for x in range(17,primeLim,2) if 1==pow(2,x-1,x)==pow(3,x-1,x)==pow(5,x-1,x)==pow(7,x-1,x)==pow(11,x-1,x)==pow(13,x-1,x)] taub, e2, hitau = 2, 1, 0 # e2 = exponent of 2 # In loop, taua = tau(k-1); taub = tau(k); e2 = power of 2 in (k-1)*k for k in range(3,primeLim*primeLim): taua = taub (taub, f2) = tau(k) if f2: e2 = f2 # If f is even, update e2 ttau = taua*taub*e2/(e2+1) if ttau &gt; hitau: hitau = ttau print '{:3} {:3} {:3}'.format(k-1, k, ttau) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload