ZealOS/docs/Demo/MagicPairs.CC.html
TomAwezome 1b75d91002 Fix Mount AHCI Port selection.
Add arg to SATARep to specify drive types to show.
Add checks in AHCIPortInit to verify port signatures, add helper method to get signatures from port.
2021-08-02 16:40:05 -04:00

450 lines
37 KiB
HTML
Executable file

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<meta name="generator" content="ZealOS V0.13">
<style type="text/css">
body {background-color:#fef1f0;}
.cF0{color:#000000;background-color:#fef1f0;}
.cF1{color:#0148a4;background-color:#fef1f0;}
.cF2{color:#3b7901;background-color:#fef1f0;}
.cF3{color:#057c7e;background-color:#fef1f0;}
.cF4{color:#bb2020;background-color:#fef1f0;}
.cF5{color:#9e42ae;background-color:#fef1f0;}
.cF6{color:#b57901;background-color:#fef1f0;}
.cF7{color:#b2b6af;background-color:#fef1f0;}
.cF8{color:#555753;background-color:#fef1f0;}
.cF9{color:#678fbb;background-color:#fef1f0;}
.cFA{color:#82bc49;background-color:#fef1f0;}
.cFB{color:#0097a2;background-color:#fef1f0;}
.cFC{color:#e26a6a;background-color:#fef1f0;}
.cFD{color:#c671bc;background-color:#fef1f0;}
.cFE{color:#c7ab00;background-color:#fef1f0;}
.cFF{color:#fef1f0;background-color:#fef1f0;}
</style>
</head>
<body>
<pre style="font-family:monospace;font-size:12pt">
<a name="l1"></a><span class=cF2>/*The magic pairs problem:</span><span class=cF0>
<a name="l2"></a>
<a name="l3"></a></span><span class=cF2>Let SumFact(n) be the sum of factors</span><span class=cF0>
<a name="l4"></a></span><span class=cF2>of n.</span><span class=cF0>
<a name="l5"></a>
<a name="l6"></a></span><span class=cF2>Find all n1,n2 in a range such that</span><span class=cF0>
<a name="l7"></a>
<a name="l8"></a></span><span class=cF2>SumFact(n1)-n1-1 == n2</span><span class=cF0> </span><span class=cF2>and</span><span class=cF0>
<a name="l9"></a></span><span class=cF2>SumFact(n2)-n2-1 == n1</span><span class=cF0>
<a name="l10"></a>
<a name="l11"></a></span><span class=cF2>-----------------------------------------------------</span><span class=cF0>
<a name="l12"></a></span><span class=cF2>To find SumFact(k), start with prime factorization:</span><span class=cF0>
<a name="l13"></a>
<a name="l14"></a></span><span class=cF2>k=(p1^n1)(p2^n2) ... (pN^nN)</span><span class=cF0>
<a name="l15"></a>
<a name="l16"></a></span><span class=cF2>THEN,</span><span class=cF0>
<a name="l17"></a>
<a name="l18"></a></span><span class=cF2>SumFact(k)=(1+p1+p1^2...p1^n1)*(1+p2+p2^2...p2^n2)*</span><span class=cF0>
<a name="l19"></a></span><span class=cF2>(1+pN+pN^2...pN^nN)</span><span class=cF0>
<a name="l20"></a>
<a name="l21"></a></span><span class=cF2>PROOF:</span><span class=cF0>
<a name="l22"></a>
<a name="l23"></a></span><span class=cF2>Do a couple examples -- it's obvious:</span><span class=cF0>
<a name="l24"></a>
<a name="l25"></a></span><span class=cF2>48=2^4*3</span><span class=cF0>
<a name="l26"></a>
<a name="l27"></a></span><span class=cF2>SumFact(48)=(1+2+4+8+16)*(1+3)=1+2+4+8+16+3+6+12+24+48</span><span class=cF0>
<a name="l28"></a>
<a name="l29"></a></span><span class=cF2>75=3*5^2</span><span class=cF0>
<a name="l30"></a>
<a name="l31"></a></span><span class=cF2>SumFact(75)=(1+3)*(1+5+25)</span><span class=cF0> </span><span class=cF2>=1+5+25+3+15+75</span><span class=cF0>
<a name="l32"></a>
<a name="l33"></a></span><span class=cF2>Corollary:</span><span class=cF0>
<a name="l34"></a>
<a name="l35"></a></span><span class=cF2>SumFact(k)=SumFact(p1^n1)*SumFact(p2^n2)*...*SumFact(pN^nN)</span><span class=cF0>
<a name="l36"></a>
<a name="l37"></a></span><span class=cF2>*/</span><span class=cF0>
<a name="l38"></a>
<a name="l39"></a></span><span class=cF2>//Primes are needed to sqrt(N). Therefore, we can use U32.</span><span class=cF0>
<a name="l40"></a></span><span class=cF1>class</span><span class=cF0> PowPrime
<a name="l41"></a>{
<a name="l42"></a> </span><span class=cF9>I64</span><span class=cF0> n;
<a name="l43"></a> </span><span class=cF9>I64</span><span class=cF0> sumfact; </span><span class=cF2>//Sumfacts for powers of primes are needed beyond sqrt(N)</span><span class=cF0>
<a name="l44"></a>};
<a name="l45"></a>
<a name="l46"></a></span><span class=cF1>class</span><span class=cF0> Prime
<a name="l47"></a>{
<a name="l48"></a> </span><span class=cF9>U32</span><span class=cF0> prime, pow_count;
<a name="l49"></a> PowPrime *pp;
<a name="l50"></a>};
<a name="l51"></a>
<a name="l52"></a></span><span class=cF9>I64</span><span class=cF0> *PrimesNew(</span><span class=cF9>I64</span><span class=cF0> N, </span><span class=cF9>I64</span><span class=cF0> *_sqrt_primes, </span><span class=cF9>I64</span><span class=cF0> *_cbrt_primes)
<a name="l53"></a>{
<a name="l54"></a> </span><span class=cF9>I64</span><span class=cF0> i, j, sqrt = </span><span class=cF5>Ceil</span><span class=cF0>(</span><span class=cF5>Sqrt</span><span class=cF7>(</span><span class=cF0>N</span><span class=cF7>)</span><span class=cF0>), cbrt = </span><span class=cF5>Ceil</span><span class=cF0>(N ` </span><span class=cF7>(</span><span class=cFE>1</span><span class=cF0> / </span><span class=cFE>3</span><span class=cF0>.</span><span class=cFE>0</span><span class=cF7>)</span><span class=cF0>),
<a name="l55"></a> sqrt_sqrt = </span><span class=cF5>Ceil</span><span class=cF0>(</span><span class=cF5>Sqrt</span><span class=cF7>(</span><span class=cF0>sqrt</span><span class=cF7>)</span><span class=cF0>), sqrt_primes = </span><span class=cFE>0</span><span class=cF0>, cbrt_primes = </span><span class=cFE>0</span><span class=cF0>;
<a name="l56"></a> </span><span class=cF1>U8</span><span class=cF0> *s = </span><span class=cF5>CAlloc</span><span class=cF0>(</span><span class=cF7>(</span><span class=cF0>sqrt + </span><span class=cFE>1</span><span class=cF0> + </span><span class=cFE>7</span><span class=cF7>)</span><span class=cF0> / </span><span class=cFE>8</span><span class=cF0>);
<a name="l57"></a> Prime *primes, *p;
<a name="l58"></a>
<a name="l59"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>2</span><span class=cF0>; i &lt;= sqrt_sqrt; i++)
<a name="l60"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l61"></a> </span><span class=cF1>if</span><span class=cF0> (!</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>s, i</span><span class=cF7>)</span><span class=cF0>)
<a name="l62"></a> {
<a name="l63"></a> j = i * </span><span class=cFE>2</span><span class=cF0>;
<a name="l64"></a> </span><span class=cF1>while</span><span class=cF0> (j &lt;= sqrt)
<a name="l65"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l66"></a> </span><span class=cF5>Bts</span><span class=cF0>(s, j);
<a name="l67"></a> j += i;
<a name="l68"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l69"></a> }
<a name="l70"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l71"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>2</span><span class=cF0>; i &lt;= sqrt; i++)
<a name="l72"></a> </span><span class=cF1>if</span><span class=cF0> (!</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>s, i</span><span class=cF7>)</span><span class=cF0>)
<a name="l73"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l74"></a> sqrt_primes++; </span><span class=cF2>//Count primes</span><span class=cF0>
<a name="l75"></a> </span><span class=cF1>if</span><span class=cF0> (i &lt;= cbrt)
<a name="l76"></a> cbrt_primes++;
<a name="l77"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l78"></a>
<a name="l79"></a> p = primes = </span><span class=cF5>CAlloc</span><span class=cF0>(sqrt_primes * </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>Prime</span><span class=cF7>)</span><span class=cF0>);
<a name="l80"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>2</span><span class=cF0>; i &lt;= sqrt; i++)
<a name="l81"></a> </span><span class=cF1>if</span><span class=cF0> (!</span><span class=cF5>Bt</span><span class=cF7>(</span><span class=cF0>s, i</span><span class=cF7>)</span><span class=cF0>)
<a name="l82"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l83"></a> p-&gt;prime = i;
<a name="l84"></a> p++;
<a name="l85"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l86"></a> </span><span class=cF5>Free</span><span class=cF0>(s);
<a name="l87"></a>
<a name="l88"></a> *_sqrt_primes = sqrt_primes;
<a name="l89"></a> *_cbrt_primes = cbrt_primes;
<a name="l90"></a>
<a name="l91"></a> </span><span class=cF1>return</span><span class=cF0> primes;
<a name="l92"></a>}
<a name="l93"></a>
<a name="l94"></a>PowPrime *PowPrimesNew(</span><span class=cF9>I64</span><span class=cF0> N, </span><span class=cF9>I64</span><span class=cF0> sqrt_primes, Prime *primes, </span><span class=cF9>I64</span><span class=cF0> *_num_powprimes)
<a name="l95"></a>{
<a name="l96"></a> </span><span class=cF9>I64</span><span class=cF0> i, j, k, sf, num_powprimes = </span><span class=cFE>0</span><span class=cF0>;
<a name="l97"></a> Prime *p;
<a name="l98"></a> PowPrime *powprimes, *pp;
<a name="l99"></a>
<a name="l100"></a> p = primes;
<a name="l101"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; sqrt_primes; i++)
<a name="l102"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l103"></a> num_powprimes += </span><span class=cF5>Floor</span><span class=cF0>(</span><span class=cF5>Ln</span><span class=cF7>(</span><span class=cF0>N</span><span class=cF7>)</span><span class=cF0> / </span><span class=cF5>Ln</span><span class=cF7>(</span><span class=cF0>p-&gt;prime</span><span class=cF7>)</span><span class=cF0>);
<a name="l104"></a> p++;
<a name="l105"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l106"></a>
<a name="l107"></a> p = primes;
<a name="l108"></a> pp = powprimes = </span><span class=cF5>MAlloc</span><span class=cF0>(num_powprimes * </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>PowPrime</span><span class=cF7>)</span><span class=cF0>);
<a name="l109"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; sqrt_primes; i++)
<a name="l110"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l111"></a> p-&gt;pp = pp;
<a name="l112"></a> j = p-&gt;prime;
<a name="l113"></a> k = </span><span class=cFE>1</span><span class=cF0>;
<a name="l114"></a> sf = </span><span class=cFE>1</span><span class=cF0>;
<a name="l115"></a> </span><span class=cF1>while</span><span class=cF0> (j &lt; N)
<a name="l116"></a> {
<a name="l117"></a> sf += j;
<a name="l118"></a> pp-&gt;n = j;
<a name="l119"></a> pp-&gt;sumfact = sf;
<a name="l120"></a> j *= p-&gt;prime;
<a name="l121"></a> pp++;
<a name="l122"></a> p-&gt;pow_count++;
<a name="l123"></a> }
<a name="l124"></a> p++;
<a name="l125"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l126"></a> *_num_powprimes = num_powprimes;
<a name="l127"></a>
<a name="l128"></a> </span><span class=cF1>return</span><span class=cF0> powprimes;
<a name="l129"></a>}
<a name="l130"></a>
<a name="l131"></a></span><span class=cF9>I64</span><span class=cF0> SumFact(</span><span class=cF9>I64</span><span class=cF0> n, </span><span class=cF9>I64</span><span class=cF0> sqrt_primes, Prime *p)
<a name="l132"></a>{
<a name="l133"></a> </span><span class=cF9>I64</span><span class=cF0> i, k, sf = </span><span class=cFE>1</span><span class=cF0>;
<a name="l134"></a> PowPrime *pp;
<a name="l135"></a>
<a name="l136"></a> </span><span class=cF1>if</span><span class=cF0> (n &lt; </span><span class=cFE>2</span><span class=cF0>)
<a name="l137"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cFE>1</span><span class=cF0>;
<a name="l138"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; sqrt_primes; i++)
<a name="l139"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l140"></a> k = </span><span class=cFE>0</span><span class=cF0>;
<a name="l141"></a> </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>n % p-&gt;prime</span><span class=cF7>)</span><span class=cF0>)
<a name="l142"></a> {
<a name="l143"></a> n /= p-&gt;prime;
<a name="l144"></a> k++;
<a name="l145"></a> }
<a name="l146"></a> </span><span class=cF1>if</span><span class=cF0> (k)
<a name="l147"></a> {
<a name="l148"></a> pp = p-&gt;pp + (k - </span><span class=cFE>1</span><span class=cF0>);
<a name="l149"></a> sf *= pp-&gt;sumfact;
<a name="l150"></a> </span><span class=cF1>if</span><span class=cF0> (n == </span><span class=cFE>1</span><span class=cF0>)
<a name="l151"></a> </span><span class=cF1>return</span><span class=cF0> sf;
<a name="l152"></a> }
<a name="l153"></a> p++;
<a name="l154"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l155"></a>
<a name="l156"></a> </span><span class=cF1>return</span><span class=cF0> sf * (</span><span class=cFE>1</span><span class=cF0> + n); </span><span class=cF2>//Prime</span><span class=cF0>
<a name="l157"></a>}
<a name="l158"></a>
<a name="l159"></a></span><span class=cF1>Bool</span><span class=cF0> TestSumFact(</span><span class=cF9>I64</span><span class=cF0> n, </span><span class=cF9>I64</span><span class=cF0> target_sf, </span><span class=cF9>I64</span><span class=cF0> sqrt_primes, </span><span class=cF9>I64</span><span class=cF0> cbrt_primes, Prime *p)
<a name="l160"></a>{
<a name="l161"></a> </span><span class=cF9>I64</span><span class=cF0> i = </span><span class=cFE>0</span><span class=cF0>, k, b, x1, x2;
<a name="l162"></a> PowPrime *pp;
<a name="l163"></a> </span><span class=cF1>F64</span><span class=cF0> disc;
<a name="l164"></a>
<a name="l165"></a> </span><span class=cF1>if</span><span class=cF0> (n &lt; </span><span class=cFE>2</span><span class=cF0>)
<a name="l166"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l167"></a> </span><span class=cF1>while</span><span class=cF0> (i++ &lt; cbrt_primes)
<a name="l168"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l169"></a> k = </span><span class=cFE>0</span><span class=cF0>;
<a name="l170"></a> </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>n % p-&gt;prime</span><span class=cF7>)</span><span class=cF0>)
<a name="l171"></a> {
<a name="l172"></a> n /= p-&gt;prime;
<a name="l173"></a> k++;
<a name="l174"></a> }
<a name="l175"></a> </span><span class=cF1>if</span><span class=cF0> (k)
<a name="l176"></a> {
<a name="l177"></a> pp = p-&gt;pp + (k - </span><span class=cFE>1</span><span class=cF0>);
<a name="l178"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>ModU64</span><span class=cF7>(</span><span class=cF0>&amp;target_sf, pp-&gt;sumfact</span><span class=cF7>)</span><span class=cF0>)
<a name="l179"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l180"></a> </span><span class=cF1>if</span><span class=cF0> (n == </span><span class=cFE>1</span><span class=cF0>)
<a name="l181"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l182"></a> </span><span class=cF1>if</span><span class=cF0> (target_sf == </span><span class=cFE>1</span><span class=cF0>)
<a name="l183"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l184"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l185"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l186"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l187"></a> }
<a name="l188"></a> p++;
<a name="l189"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l190"></a></span><span class=cF2>/*</span><span class=cF0> </span><span class=cF2>At this point we have three possible cases to test</span><span class=cF0>
<a name="l191"></a></span><span class=cF2>1)n==p1 </span><span class=cF0> </span><span class=cF2>-&gt;sf==(1+p1)</span><span class=cF0> </span><span class=cF2>?</span><span class=cF0>
<a name="l192"></a></span><span class=cF2>2)n==p1*p1</span><span class=cF0> </span><span class=cF2>-&gt;sf==(1+p1+p1^2) </span><span class=cF0> </span><span class=cF2>?</span><span class=cF0>
<a name="l193"></a></span><span class=cF2>3)n==p1*p2</span><span class=cF0> </span><span class=cF2>-&gt;sf==(p1+1)*(p2+1) ?</span><span class=cF0>
<a name="l194"></a>
<a name="l195"></a></span><span class=cF2>*/</span><span class=cF0>
<a name="l196"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cFE>1</span><span class=cF0> + n == target_sf)
<a name="l197"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l198"></a> </span><span class=cF1>while</span><span class=cF0> (i++ &lt; sqrt_primes)
<a name="l199"></a> {
<a name="l200"></a> k = </span><span class=cFE>0</span><span class=cF0>;
<a name="l201"></a> </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>n % p-&gt;prime</span><span class=cF7>)</span><span class=cF0>)
<a name="l202"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l203"></a> n /= p-&gt;prime;
<a name="l204"></a> k++;
<a name="l205"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l206"></a> </span><span class=cF1>if</span><span class=cF0> (k)
<a name="l207"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l208"></a> pp = p-&gt;pp + (k - </span><span class=cFE>1</span><span class=cF0>);
<a name="l209"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cF5>ModU64</span><span class=cF7>(</span><span class=cF0>&amp;target_sf, pp-&gt;sumfact</span><span class=cF7>)</span><span class=cF0>)
<a name="l210"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l211"></a> </span><span class=cF1>if</span><span class=cF0> (n == </span><span class=cFE>1</span><span class=cF0>)
<a name="l212"></a> {
<a name="l213"></a> </span><span class=cF1>if</span><span class=cF0> (target_sf == </span><span class=cFE>1</span><span class=cF0>)
<a name="l214"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l215"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l216"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l217"></a> }
<a name="l218"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l219"></a> p++;
<a name="l220"></a> }
<a name="l221"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cFE>1</span><span class=cF0> + n == target_sf)
<a name="l222"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l223"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l224"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l225"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l226"></a>
<a name="l227"></a> k =</span><span class=cF5>Sqrt</span><span class=cF0>(n);
<a name="l228"></a> </span><span class=cF1>if</span><span class=cF0> (k * k == n)
<a name="l229"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l230"></a> </span><span class=cF1>if</span><span class=cF0> (</span><span class=cFE>1</span><span class=cF0> + k + n == target_sf)
<a name="l231"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l232"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l233"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l234"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l235"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l236"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l237"></a></span><span class=cF2>// n==p1*p2 -&gt; sf==(p1+1)*(p2+1) ?</span><span class=cF0> </span><span class=cF2>where p1 != 1 &amp;&amp; p2 != 1</span><span class=cF0>
<a name="l238"></a> </span><span class=cF2>// if p1==1 || p2==1, it is FALSE because we checked a single prime above.</span><span class=cF0>
<a name="l239"></a>
<a name="l240"></a> </span><span class=cF2>// sf==(p1+1)*(n/p1+1)</span><span class=cF0>
<a name="l241"></a> </span><span class=cF2>// sf==n+p1+n/p1+1</span><span class=cF0>
<a name="l242"></a> </span><span class=cF2>// sf*p1==n*p1+p1^2+n+p1</span><span class=cF0>
<a name="l243"></a> </span><span class=cF2>// p1^2+(n+1-sf)*p1+n=0</span><span class=cF0>
<a name="l244"></a> </span><span class=cF2>// x=(-b+/-sqrt(b^2-4ac))/2a</span><span class=cF0>
<a name="l245"></a> </span><span class=cF2>// a=1</span><span class=cF0>
<a name="l246"></a> </span><span class=cF2>// x=(-b+/-sqrt(b^2-4c))/2</span><span class=cF0>
<a name="l247"></a> </span><span class=cF2>// b=n+1-sf;c=n</span><span class=cF0>
<a name="l248"></a> b = n + </span><span class=cFE>1</span><span class=cF0> - target_sf;
<a name="l249"></a></span><span class=cF2>// x=(-b+/-sqrt(b^2-4n))/2</span><span class=cF0>
<a name="l250"></a> disc = b * b - </span><span class=cFE>4</span><span class=cF0> * n;
<a name="l251"></a> </span><span class=cF1>if</span><span class=cF0> (disc &lt; </span><span class=cFE>0</span><span class=cF0>)
<a name="l252"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l253"></a> x1 = (-b - </span><span class=cF5>Sqrt</span><span class=cF7>(</span><span class=cF0>disc</span><span class=cF7>)</span><span class=cF0>) / </span><span class=cFE>2</span><span class=cF0>;
<a name="l254"></a> </span><span class=cF1>if</span><span class=cF0> (x1 &lt;= </span><span class=cFE>1</span><span class=cF0>)
<a name="l255"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l256"></a> x2 = n / x1;
<a name="l257"></a> </span><span class=cF1>if</span><span class=cF0> (x2 &gt; </span><span class=cFE>1</span><span class=cF0> &amp;&amp; x1 * x2 == n)
<a name="l258"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>TRUE</span><span class=cF0>;
<a name="l259"></a> </span><span class=cF1>else</span><span class=cF0>
<a name="l260"></a> </span><span class=cF1>return</span><span class=cF0> </span><span class=cF3>FALSE</span><span class=cF0>;
<a name="l261"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l262"></a>}
<a name="l263"></a>
<a name="l264"></a></span><span class=cF1>U0</span><span class=cF0> PutFactors(</span><span class=cF9>I64</span><span class=cF0> n) </span><span class=cF2>//For debugging</span><span class=cF0>
<a name="l265"></a>{
<a name="l266"></a> </span><span class=cF9>I64</span><span class=cF0> i, k, sqrt = </span><span class=cF5>Ceil</span><span class=cF0>(</span><span class=cF5>Sqrt</span><span class=cF7>(</span><span class=cF0>n</span><span class=cF7>)</span><span class=cF0>);
<a name="l267"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>2</span><span class=cF0>; i &lt;= sqrt; i++)
<a name="l268"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l269"></a> k = </span><span class=cFE>0</span><span class=cF0>;
<a name="l270"></a> </span><span class=cF1>while</span><span class=cF0> (!</span><span class=cF7>(</span><span class=cF0>n % i</span><span class=cF7>)</span><span class=cF0>)
<a name="l271"></a> {
<a name="l272"></a> k++;
<a name="l273"></a> n /= i;
<a name="l274"></a> }
<a name="l275"></a> </span><span class=cF1>if</span><span class=cF0> (k)
<a name="l276"></a> {
<a name="l277"></a> </span><span class=cF6>&quot;%d&quot;</span><span class=cF0>, i;
<a name="l278"></a> </span><span class=cF1>if</span><span class=cF0> (k &gt; </span><span class=cFE>1</span><span class=cF0>)
<a name="l279"></a> </span><span class=cF6>&quot;^%d&quot;</span><span class=cF0>, k;
<a name="l280"></a> </span><span class=cF6>''</span><span class=cF0> </span><span class=cF3>CH_SPACE</span><span class=cF0>;
<a name="l281"></a> }
<a name="l282"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l283"></a> </span><span class=cF1>if</span><span class=cF0> (n != </span><span class=cFE>1</span><span class=cF0>)
<a name="l284"></a> </span><span class=cF6>&quot;%d &quot;</span><span class=cF0>, n;
<a name="l285"></a>}
<a name="l286"></a>
<a name="l287"></a></span><span class=cF1>class</span><span class=cF0> RangeJob
<a name="l288"></a>{
<a name="l289"></a> </span><span class=cF9>CDoc</span><span class=cF0> *doc;
<a name="l290"></a> </span><span class=cF9>I64</span><span class=cF0> num, lo, hi, N, sqrt_primes, cbrt_primes;
<a name="l291"></a> Prime *primes;
<a name="l292"></a> </span><span class=cF9>CJob</span><span class=cF0> *cmd;
<a name="l293"></a>
<a name="l294"></a>} rj[</span><span class=cFB>mp_count</span><span class=cF0>];
<a name="l295"></a>
<a name="l296"></a></span><span class=cF9>I64</span><span class=cF0> TestCoreSubRange(RangeJob *r)
<a name="l297"></a>{
<a name="l298"></a> </span><span class=cF9>I64</span><span class=cF0> i, j, m, n, n2, sf, res = </span><span class=cFE>0</span><span class=cF0>, range = r-&gt;hi - r-&gt;lo,
<a name="l299"></a> *sumfacts = </span><span class=cF5>MAlloc</span><span class=cF0>(range * </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF9>I64</span><span class=cF7>)</span><span class=cF0>),
<a name="l300"></a> *residue = </span><span class=cF5>MAlloc</span><span class=cF0>(range * </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF9>I64</span><span class=cF7>)</span><span class=cF0>);
<a name="l301"></a> </span><span class=cF9>U16</span><span class=cF0> *pow_count = </span><span class=cF5>MAlloc</span><span class=cF0>(range * </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF9>U16</span><span class=cF7>)</span><span class=cF0>);
<a name="l302"></a> Prime *p = r-&gt;primes;
<a name="l303"></a> PowPrime *pp;
<a name="l304"></a>
<a name="l305"></a> </span><span class=cF5>MemSetI64</span><span class=cF0>(sumfacts, </span><span class=cFE>1</span><span class=cF0>, range);
<a name="l306"></a> </span><span class=cF1>for</span><span class=cF0> (n = r-&gt;lo; n &lt; r-&gt;hi; n++)
<a name="l307"></a> residue[n - r-&gt;lo] = n;
<a name="l308"></a> </span><span class=cF1>for</span><span class=cF0> (j = </span><span class=cFE>0</span><span class=cF0>; j &lt;r-&gt;sqrt_primes; j++)
<a name="l309"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l310"></a> </span><span class=cF5>MemSet</span><span class=cF0>(pow_count, </span><span class=cFE>0</span><span class=cF0>, range * </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF9>U16</span><span class=cF7>)</span><span class=cF0>);
<a name="l311"></a> m = </span><span class=cFE>1</span><span class=cF0>;
<a name="l312"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; p-&gt;pow_count; i++)
<a name="l313"></a> {
<a name="l314"></a> m *= p-&gt;prime;
<a name="l315"></a> n = m - r-&gt;lo % m;
<a name="l316"></a> </span><span class=cF1>while</span><span class=cF0> (n &lt; range)
<a name="l317"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l318"></a> pow_count[n]++;
<a name="l319"></a> n += m;
<a name="l320"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l321"></a> }
<a name="l322"></a> </span><span class=cF1>for</span><span class=cF0> (n = </span><span class=cFE>0</span><span class=cF0>; n &lt; range; n++)
<a name="l323"></a> </span><span class=cF1>if</span><span class=cF0> (i = pow_count[n])
<a name="l324"></a> {
<a name="l325"></a> pp = &amp;p-&gt;pp[i - </span><span class=cFE>1</span><span class=cF0>];
<a name="l326"></a> sumfacts[n] *= pp-&gt;sumfact;
<a name="l327"></a> residue [n] /= pp-&gt;n;
<a name="l328"></a> }
<a name="l329"></a> p++;
<a name="l330"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l331"></a>
<a name="l332"></a> </span><span class=cF1>for</span><span class=cF0> (n = </span><span class=cFE>0</span><span class=cF0>; n &lt; range; n++)
<a name="l333"></a> </span><span class=cF1>if</span><span class=cF0> (residue[n] != </span><span class=cFE>1</span><span class=cF0>)
<a name="l334"></a> sumfacts[n] *= </span><span class=cFE>1</span><span class=cF0> + residue[n];
<a name="l335"></a>
<a name="l336"></a> </span><span class=cF1>for</span><span class=cF0> (n = r-&gt;lo; n &lt; r-&gt;hi; n++)
<a name="l337"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l338"></a> sf = sumfacts[n - r-&gt;lo];
<a name="l339"></a> n2 = sf - n - </span><span class=cFE>1</span><span class=cF0>;
<a name="l340"></a> </span><span class=cF1>if</span><span class=cF0> (n &lt; n2 &lt; r-&gt;N)
<a name="l341"></a> {
<a name="l342"></a> </span><span class=cF1>if</span><span class=cF0> (r-&gt;lo &lt;= n2&lt;r-&gt;hi &amp;&amp; sumfacts[n2 - r-&gt;lo] - n2 - </span><span class=cFE>1</span><span class=cF0> == n ||
<a name="l343"></a> TestSumFact</span><span class=cF7>(</span><span class=cF0>n2, sf, r-&gt;sqrt_primes, r-&gt;cbrt_primes, r-&gt;primes</span><span class=cF7>)</span><span class=cF0>)
<a name="l344"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l345"></a> </span><span class=cF5>DocPrint</span><span class=cF0>(r-&gt;doc, </span><span class=cF6>&quot;%u:%u\n&quot;</span><span class=cF0>, n, sf - n - </span><span class=cFE>1</span><span class=cF0>);
<a name="l346"></a> res++;
<a name="l347"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l348"></a> }
<a name="l349"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l350"></a> </span><span class=cF5>Free</span><span class=cF0>(pow_count);
<a name="l351"></a> </span><span class=cF5>Free</span><span class=cF0>(residue);
<a name="l352"></a> </span><span class=cF5>Free</span><span class=cF0>(sumfacts);
<a name="l353"></a>
<a name="l354"></a> </span><span class=cF1>return</span><span class=cF0> res;
<a name="l355"></a>}
<a name="l356"></a>
<a name="l357"></a>#</span><span class=cF1>define</span><span class=cF0> CORE_SUB_RANGE </span><span class=cFE>0x1000</span><span class=cF0>
<a name="l358"></a>
<a name="l359"></a></span><span class=cF9>I64</span><span class=cF0> TestCoreRange(RangeJob *r)
<a name="l360"></a>{
<a name="l361"></a> </span><span class=cF9>I64</span><span class=cF0> i, n, res = </span><span class=cFE>0</span><span class=cF0>;
<a name="l362"></a> RangeJob rj;
<a name="l363"></a>
<a name="l364"></a> </span><span class=cF5>MemCopy</span><span class=cF0>(&amp;rj, r, </span><span class=cF1>sizeof</span><span class=cF7>(</span><span class=cF0>RangeJob</span><span class=cF7>)</span><span class=cF0>);
<a name="l365"></a> </span><span class=cF1>for</span><span class=cF0> (i = r-&gt;lo; i &lt; r-&gt;hi; i += CORE_SUB_RANGE)
<a name="l366"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l367"></a> rj.lo = i;
<a name="l368"></a> rj.hi = i + CORE_SUB_RANGE;
<a name="l369"></a> </span><span class=cF1>if</span><span class=cF0> (rj.hi &gt; r-&gt;hi)
<a name="l370"></a> rj.hi = r-&gt;hi;
<a name="l371"></a> res += TestCoreSubRange(&amp;rj);
<a name="l372"></a>
<a name="l373"></a> n = rj.hi - rj.lo;
<a name="l374"></a> </span><span class=cF1>lock</span><span class=cF0> {</span><span class=cFB>progress1</span><span class=cF0> += n;}
<a name="l375"></a>
<a name="l376"></a> </span><span class=cF5>Yield</span><span class=cF0>;
<a name="l377"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l378"></a>
<a name="l379"></a> </span><span class=cF1>return</span><span class=cF0> res;
<a name="l380"></a>}
<a name="l381"></a>
<a name="l382"></a></span><span class=cF9>I64</span><span class=cF0> MagicPairs(</span><span class=cF9>I64</span><span class=cF0> N)
<a name="l383"></a>{
<a name="l384"></a> </span><span class=cF1>F64</span><span class=cF0> t0 = </span><span class=cF5>tS</span><span class=cF0>;
<a name="l385"></a> </span><span class=cF9>I64</span><span class=cF0> res = </span><span class=cFE>0</span><span class=cF0>;
<a name="l386"></a> </span><span class=cF9>I64</span><span class=cF0> sqrt_primes, cbrt_primes, num_powprimes,
<a name="l387"></a> i, k, n = (N - </span><span class=cFE>1</span><span class=cF0>) / </span><span class=cFB>mp_count</span><span class=cF0> + </span><span class=cFE>1</span><span class=cF0>;
<a name="l388"></a> Prime *primes = PrimesNew(N, &amp;sqrt_primes, &amp;cbrt_primes);
<a name="l389"></a> PowPrime *powprimes = PowPrimesNew(N, sqrt_primes, primes, &amp;num_powprimes);
<a name="l390"></a>
<a name="l391"></a> </span><span class=cF6>&quot;N:%u SqrtPrimes:%u CbrtPrimes:%u PowersOfPrimes:%u\n&quot;</span><span class=cF0>, N, sqrt_primes, cbrt_primes, num_powprimes;
<a name="l392"></a> </span><span class=cFB>progress1</span><span class=cF0> = </span><span class=cFE>0</span><span class=cF0>;
<a name="l393"></a> *</span><span class=cFB>progress1_desc</span><span class=cF0> = </span><span class=cFE>0</span><span class=cF0>;
<a name="l394"></a> </span><span class=cFB>progress1_max</span><span class=cF0> = N;
<a name="l395"></a> k = </span><span class=cFE>2</span><span class=cF0>;
<a name="l396"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFB>mp_count</span><span class=cF0>; i++)
<a name="l397"></a> </span><span class=cF7>{</span><span class=cF0>
<a name="l398"></a> rj[i].doc = </span><span class=cF5>DocPut</span><span class=cF0>;
<a name="l399"></a> rj[i].num = i;
<a name="l400"></a> rj[i].lo = k;
<a name="l401"></a> k += n;
<a name="l402"></a> </span><span class=cF1>if</span><span class=cF0> (k &gt; N)
<a name="l403"></a> k = N;
<a name="l404"></a> rj[i].hi = k;
<a name="l405"></a> rj[i].N = N;
<a name="l406"></a> rj[i].sqrt_primes = sqrt_primes;
<a name="l407"></a> rj[i].cbrt_primes = cbrt_primes;
<a name="l408"></a> rj[i].primes = primes;
<a name="l409"></a> rj[i].cmd = </span><span class=cF5>JobQueue</span><span class=cF0>(&amp;TestCoreRange, &amp;rj[i], </span><span class=cFB>mp_count</span><span class=cF0> - </span><span class=cFE>1</span><span class=cF0> - i, </span><span class=cFE>0</span><span class=cF0>);
<a name="l410"></a> </span><span class=cF7>}</span><span class=cF0>
<a name="l411"></a> </span><span class=cF1>for</span><span class=cF0> (i = </span><span class=cFE>0</span><span class=cF0>; i &lt; </span><span class=cFB>mp_count</span><span class=cF0>; i++)
<a name="l412"></a> res += </span><span class=cF5>JobResGet</span><span class=cF0>(rj[i].cmd);
<a name="l413"></a> </span><span class=cF5>Free</span><span class=cF0>(powprimes);
<a name="l414"></a> </span><span class=cF5>Free</span><span class=cF0>(primes);
<a name="l415"></a> </span><span class=cF6>&quot;Found:%u Time:%9.4f\n&quot;</span><span class=cF0>, res, </span><span class=cF5>tS</span><span class=cF0> - t0;
<a name="l416"></a> </span><span class=cFB>progress1</span><span class=cF0> = </span><span class=cFB>progress1_max</span><span class=cF0> = </span><span class=cFE>0</span><span class=cF0>;
<a name="l417"></a>
<a name="l418"></a> </span><span class=cF1>return</span><span class=cF0> res;
<a name="l419"></a>}
<a name="l420"></a>
<a name="l421"></a>MagicPairs(</span><span class=cFE>1000000</span><span class=cF0>);
</span></pre></body>
</html>