Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>For really large numbers <code>n</code>, you can use the following math trick to speed up the operation of </p> <pre><code> n % 3 == 0 </code></pre> <p>which is really slow and most likely the choke point of any algorithm that relies on repeated checking of remainders. You have to understand modular arithmetic to follow what I am doing, which is part of elementary number theory.</p> <p>Let x = &Sigma; <sub>k</sub> a <sub>k</sub> 2 <sup> k </sup> be the number of interest. We can let the upper bound of the sum be &infin; with the understanding that a <sub>k</sub> = 0 for some k > M. Then</p> <p>0 &equiv; x &equiv; &Sigma; <sub>k</sub> a <sub>k</sub> 2 <sup> k </sup> &equiv; &Sigma; <sub>k</sub> a <sub>2k</sub> 2 <sup>2k</sup> + a <sub>2k+1</sub> 2 <sup>2k+1</sup> &equiv; &Sigma; <sub>k</sub> 2 <sup>2k</sup> ( a <sub>2k</sub> + a <sub>2k+1</sub> 2) &equiv; &Sigma; <sub>k</sub> a <sub>2k</sub> + a <sub>2k+1</sub> 2 (mod 3)</p> <p>since 2<sup>2k</sup> &equiv; 4 <sup>k</sup> &equiv; 1<sup>k</sup> &equiv; 1 (mod 3).</p> <p>Given a binary representation of a number x with 2n+1 bits as </p> <p>x<sub>0</sub> x<sub>1</sub> x<sub>2</sub> ... x<sub>2n+1</sub></p> <p>where x<sub>k</sub> &isin;{0,1} you can group odd even pairs</p> <p>(x<sub>0</sub> x<sub>1</sub>) (x<sub>2</sub> x<sub>3</sub>) ... (x<sub>2n</sub> x<sub>2n+1</sub>).</p> <p>Let q denote the number of pairings of the form (1 0) and let r denote the number of pairings of the form (0 1). Then it follows from the equation above that 3 | x if and only if 3 | (q + 2r). Furthermore, you can show that 3|(q + 2r) if and only if q and r have the same remainder when divided by 3.</p> <p>So an algorithm for determining whether a number is divisible by 3 could be done as follows</p> <pre><code> q = 0, r = 0 for i in {0,1, .., n} pair &lt;- (x_{2i} x_{2i+1}) if pair == (1 0) switch(q) case 0: q = 1; break; case 1: q = 2; break; case 2: q = 0; break; else if pair == (0 1) switch(r) case 0: r = 1; break; case 1: r = 2; break; case 2: r = 0; return q == r </code></pre> <p>This algorithm is more efficient than the use of %.</p> <p>--- Edit many years later ----</p> <p>I took a few minutes to implement a rudimentary version of this in python that checks its true for all numbers up to 10^4. I include it below for reference. Obviously, to make use of this one would implement this as close to hardware as possible. This scanning technique can be extended to any number that one wants to by altering the derivation. I also conjecture the 'scanning' portion of the algorithm can be reformulated in a recursive <code>O(log n)</code> type formulation similar to a FFT, but I'd have to think on it. </p> <pre><code>#!/usr/bin/python def bits2num(bits): num = 0 for i,b in enumerate(bits): num += int(b) &lt;&lt; i return num def num2bits(num): base = 0 bits = list() while True: op = 1 &lt;&lt; base if op &gt; num: break bits.append(op&amp;num !=0) base += 1 return "".join(map(str,map(int,bits)))[::-1] def div3(bits): n = len(bits) if n % 2 != 0: bits = bits + '0' n = len(bits) assert n % 2 == 0 q = 0 r = 0 for i in range(n/2): pair = bits[2*i:2*i+2] if pair == '10': if q == 0: q = 1 elif q == 1: q = 2 elif q == 2: q = 0 elif pair == '01': if r == 0: r = 1 elif r == 1: r = 2 elif r == 2: r = 0 else: pass return q == r for i in range(10000): truth = (i % 3) == 0 bits = num2bits(i) check = div3(bits) assert truth == check </code></pre>
    singulars
    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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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