Figured out problem with Fermat test in problem 58.

This commit is contained in:
2019-02-02 12:22:43 -05:00
parent fe73c53c46
commit 45c7e862d3
3 changed files with 160 additions and 57 deletions

View File

@@ -11846,7 +11846,7 @@ div#notebook {
<span class="k">return</span> <span class="p">(</span><span class="n">base</span> <span class="o">*</span> <span class="n">expmod</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">exp</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span> <span class="o">%</span> <span class="n">m</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">fermat_test</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">fermat_test_sicp</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">40</span><span class="p">:</span>
<span class="k">return</span> <span class="n">n</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mi">29</span><span class="p">,</span> <span class="mi">31</span><span class="p">,</span> <span class="mi">37</span><span class="p">,</span> <span class="mi">39</span><span class="p">]</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">3</span>
@@ -11910,10 +11910,10 @@ div#notebook {
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="n">trial_division</span><span class="p">(</span><span class="n">n</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">n</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">3</span><span class="p">))</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">107</span><span class="p">))</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">108</span><span class="p">)</span> <span class="o">==</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">109</span><span class="p">))</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test_sicp</span><span class="p">(</span><span class="mi">3</span><span class="p">))</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test_sicp</span><span class="p">(</span><span class="mi">107</span><span class="p">))</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test_sicp</span><span class="p">(</span><span class="mi">108</span><span class="p">)</span> <span class="o">==</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test_sicp</span><span class="p">(</span><span class="mi">109</span><span class="p">))</span>
</pre></div>
</div>
</div>
@@ -11989,7 +11989,7 @@ div#notebook {
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [5]:</div>
<div class="prompt input_prompt">In [12]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">import</span> <span class="nn">random</span>
@@ -11997,27 +11997,14 @@ div#notebook {
<span class="k">def</span> <span class="nf">is_prime</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">n</span> <span class="o">-</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">expmod</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="o">==</span> <span class="n">a</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">3</span><span class="p">))</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">107</span><span class="p">))</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">108</span><span class="p">)</span> <span class="o">==</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">assert</span><span class="p">(</span><span class="n">fermat_test</span><span class="p">(</span><span class="mi">109</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [6]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="n">get_solution</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">get_solution</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Expected n is 26241."</span><span class="p">)</span>
</pre></div>
</div>
</div>
@@ -12028,6 +12015,8 @@ div#notebook {
<div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>n: 26641 count_total: 53281 count_primes: 5328 ratio: 0.09999812315834913
26641
Expected n is 26241.
</pre>
</div>
</div>
@@ -12046,6 +12035,70 @@ div#notebook {
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [10]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">carmichael_number</span> <span class="o">=</span> <span class="p">[</span><span class="mi">561</span><span class="p">,</span> <span class="mi">1105</span><span class="p">,</span> <span class="mi">1729</span><span class="p">,</span> <span class="mi">2465</span><span class="p">,</span> <span class="mi">2821</span><span class="p">,</span> <span class="mi">6601</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">little_fermat</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">p</span><span class="p">):</span> <span class="c1"># SICP uses this</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a</span> <span class="o">**</span> <span class="n">p</span><span class="p">)</span> <span class="o">%</span> <span class="n">p</span> <span class="o">==</span> <span class="n">a</span> <span class="o">%</span> <span class="n">p</span>
<span class="k">def</span> <span class="nf">little_fermat_simple</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">p</span><span class="p">):</span> <span class="c1"># Wikipedia uses this</span>
<span class="k">assert</span><span class="p">(</span><span class="n">a</span> <span class="o">&lt;</span> <span class="n">p</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a</span> <span class="o">**</span> <span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="o">%</span> <span class="n">p</span> <span class="o">==</span> <span class="mi">1</span>
<span class="k">def</span> <span class="nf">expmod</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">exp</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
<span class="k">if</span> <span class="n">exp</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">if</span> <span class="p">(</span><span class="n">exp</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="n">expmod</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">exp</span> <span class="o">//</span> <span class="mi">2</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">%</span> <span class="n">m</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">base</span> <span class="o">*</span> <span class="n">expmod</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">exp</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span> <span class="o">%</span> <span class="n">m</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">fermat_test</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="n">ps</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mi">29</span><span class="p">,</span> <span class="mi">31</span><span class="p">,</span> <span class="mi">37</span><span class="p">,</span> <span class="mi">39</span><span class="p">]</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&lt;=</span> <span class="n">ps</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
<span class="k">return</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">ps</span>
<span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">ps</span><span class="p">:</span>
<span class="c1">#if not little_fermat_simple(a, n):</span>
<span class="k">if</span> <span class="n">expmod</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1">#print("Fermat witness for {} is {}.".format(n + 1, a))</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">is_prime</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">return</span> <span class="n">fermat_test</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">get_solution</span><span class="p">())</span>
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">carmichael_number</span><span class="p">:</span>
<span class="n">r_sicp</span> <span class="o">=</span> <span class="n">fermat_test_sicp</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">fermat_test</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"For </span><span class="si">{}</span><span class="s2"> sicp says </span><span class="si">{}</span><span class="s2"> and real test says </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">r_sicp</span><span class="p">,</span> <span class="n">r</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="prompt"></div>
<div class="output_subarea output_stream output_stdout output_text">
<pre>n: 26241 count_total: 52481 count_primes: 5248 ratio: 0.09999809454850327
26241
For 561 sicp says True and real test says False.
For 1105 sicp says True and real test says False.
For 1729 sicp says True and real test says False.
For 2465 sicp says True and real test says False.
For 2821 sicp says True and real test says False.
For 6601 sicp says True and real test says False.
</pre>
</div>
</div>
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
<div class="input_area">