Figured out problem with Fermat test in problem 58.
parent
fe73c53c46
commit
45c7e862d3
|
@ -33,7 +33,9 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def get_last_corner_value(side_length):\n",
|
||||
|
@ -81,7 +83,7 @@
|
|||
" return (base * expmod(base, exp - 1, m) % m)\n",
|
||||
" \n",
|
||||
"\n",
|
||||
"def fermat_test(n):\n",
|
||||
"def fermat_test_sicp(n):\n",
|
||||
" if n < 40:\n",
|
||||
" return n in [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39]\n",
|
||||
" a = n - 3\n",
|
||||
|
@ -145,10 +147,10 @@
|
|||
" return False\n",
|
||||
" return trial_division(n)[0] == n\n",
|
||||
"\n",
|
||||
"assert(fermat_test(3))\n",
|
||||
"assert(fermat_test(107))\n",
|
||||
"assert(fermat_test(108) == False)\n",
|
||||
"assert(fermat_test(109))"
|
||||
"assert(fermat_test_sicp(3))\n",
|
||||
"assert(fermat_test_sicp(107))\n",
|
||||
"assert(fermat_test_sicp(108) == False)\n",
|
||||
"assert(fermat_test_sicp(109))"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -210,44 +212,33 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import random\n",
|
||||
"\n",
|
||||
"def is_prime(n):\n",
|
||||
" if n == 1:\n",
|
||||
" return False\n",
|
||||
" for _ in range(100):\n",
|
||||
" a = n - random.randint(1, n - 1)\n",
|
||||
" if not expmod(a, n, n) == a:\n",
|
||||
" return False\n",
|
||||
" return True\n",
|
||||
"\n",
|
||||
"assert(fermat_test(3))\n",
|
||||
"assert(fermat_test(107))\n",
|
||||
"assert(fermat_test(108) == False)\n",
|
||||
"assert(fermat_test(109))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"n: 26641 count_total: 53281 count_primes: 5328 ratio: 0.09999812315834913\n"
|
||||
"n: 26641 count_total: 53281 count_primes: 5328 ratio: 0.09999812315834913\n",
|
||||
"26641\n",
|
||||
"Expected n is 26241.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"s = get_solution()"
|
||||
"import random\n",
|
||||
"\n",
|
||||
"def is_prime(n):\n",
|
||||
" if n == 1:\n",
|
||||
" return False\n",
|
||||
" for _ in range(10):\n",
|
||||
" a = n - random.randint(1, n - 1)\n",
|
||||
" if not expmod(a, n, n) == a:\n",
|
||||
" return False\n",
|
||||
" return True\n",
|
||||
"\n",
|
||||
"print(get_solution())\n",
|
||||
"print(\"Expected n is 26241.\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -261,6 +252,65 @@
|
|||
"Try this algorithm instead [https://en.wikipedia.org/wiki/Miller–Rabin_primality_test](https://en.wikipedia.org/wiki/Miller–Rabin_primality_test)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"n: 26241 count_total: 52481 count_primes: 5248 ratio: 0.09999809454850327\n",
|
||||
"26241\n",
|
||||
"For 561 sicp says True and real test says False.\n",
|
||||
"For 1105 sicp says True and real test says False.\n",
|
||||
"For 1729 sicp says True and real test says False.\n",
|
||||
"For 2465 sicp says True and real test says False.\n",
|
||||
"For 2821 sicp says True and real test says False.\n",
|
||||
"For 6601 sicp says True and real test says False.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"carmichael_number = [561, 1105, 1729, 2465, 2821, 6601]\n",
|
||||
"\n",
|
||||
"def little_fermat(a, p): # SICP uses this\n",
|
||||
" return (a ** p) % p == a % p\n",
|
||||
"\n",
|
||||
"def little_fermat_simple(a, p): # Wikipedia uses this\n",
|
||||
" assert(a < p)\n",
|
||||
" return (a ** (p - 1)) % p == 1\n",
|
||||
"\n",
|
||||
"def expmod(base, exp, m):\n",
|
||||
" if exp == 0:\n",
|
||||
" return 1\n",
|
||||
" if (exp % 2 == 0):\n",
|
||||
" return (expmod(base, exp // 2, m) ** 2 % m)\n",
|
||||
" return (base * expmod(base, exp - 1, m) % m)\n",
|
||||
"\n",
|
||||
"def fermat_test(n):\n",
|
||||
" ps = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39]\n",
|
||||
" if n <= ps[-1]:\n",
|
||||
" return n in ps\n",
|
||||
" for a in ps:\n",
|
||||
" #if not little_fermat_simple(a, n):\n",
|
||||
" if expmod(a, n - 1, n) != 1:\n",
|
||||
" #print(\"Fermat witness for {} is {}.\".format(n + 1, a))\n",
|
||||
" return False\n",
|
||||
" return True\n",
|
||||
"\n",
|
||||
"def is_prime(n):\n",
|
||||
" return fermat_test(n)\n",
|
||||
"\n",
|
||||
"print(get_solution())\n",
|
||||
"\n",
|
||||
"for n in carmichael_number:\n",
|
||||
" r_sicp = fermat_test_sicp(n)\n",
|
||||
" r = fermat_test(n)\n",
|
||||
" print(\"For {} sicp says {} and real test says {}.\".format(n, r_sicp, r))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
|
|
@ -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"><</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"><</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"><=</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">
|
||||
|
|
|
@ -11770,7 +11770,7 @@ div#notebook {
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h1 id="Problem-Name-(Euler-Problem-xxx)">Problem Name (Euler Problem xxx)<a class="anchor-link" href="#Problem-Name-(Euler-Problem-xxx)">¶</a></h1><p><a href="/euler">Back to overview.</a></p>
|
||||
<h1 id="Magic-5-gon-ring-(Euler-Problem-68)">Magic 5-gon ring (Euler Problem 68)<a class="anchor-link" href="#Magic-5-gon-ring-(Euler-Problem-68)">¶</a></h1><p><a href="/euler">Back to overview.</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue