-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathassignment-two.xml
150 lines (150 loc) · 9.79 KB
/
assignment-two.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<sheaf>
<section>
<assignment title="Modular Arithmetic, Random Numbers, and Primes">
<instructions>
<text><![CDATA[
In this assignment you will solve several equations, and you will define a collection of Python functions that will allow you to generate probable prime numbers of any size. You must submit a single Python source file named <code>hw2/hw2.py</code>. Please follow the <a href="#A">gsubmit</a> directions.
]]></text>
<paragraph><![CDATA[
You may import the following library functions in your module:
]]></paragraph>
<code class="py"><![CDATA[
from fractions import gcd
from math import log
]]></code>
<text hooks="math"><![CDATA[
You may also use:
<ul>
<li>the <code>.bit_length()</code> method to efficiently obtain the bit length of an integer,</li>
<li>the built-in <code>pow()</code> function to compute modular exponents efficiently (i.e., a^{%k} \mod %n can be written in Python as <code>pow(a,k,n)</code>),</li>
<li>the <code>abs()</code> function for computing the absolute value of an integer,</li>
<li>and the <code>//</code> operator for integer division (you should avoid using <code>/</code> because it does not work for very large integers).</li>
</ul>
<b style="color:firebrick;">Your file may not import any other modules or employ any external library functions associated with integers and sets unless explicitly permitted to do so in a particular problem.</b>
]]></text>
<paragraph><![CDATA[
Solutions to each of the programming problem parts below should be fairly concise. You will be graded on the correctness, concision, and mathematical legibility of your code. The different problems and problem parts rely on the lecture notes and on each other; carefully consider whether you can use functions from the lecture notes, or functions you define in one part within subsequent parts.
]]></paragraph>
</instructions>
<problems>
<problem>
<text hooks="math"><![CDATA[
Solve the following equations using step-by-step equational reasoning, and list each step. You must list all solutions (zero or more) for %x. You may need to use some automation to perform some of the steps (e.g., to check whether a number is prime or whether two numbers are coprime). Your solutions for this problem should appear as comments, delimited using <code>'''</code>...<code>'''</code>, in <code>hw2.py</code>. You may use the <code>=</code> ASCII character to represent the \equiv relational operator on congruence classes.
]]></text>
<parts>
<part>
<text hooks="math"><![CDATA[4 \cdot %x + 1 \equiv 9 (\mod 17)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[5 \cdot %x + 2 \equiv %- 6 (\mod 11)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[10 \cdot %x %- 2 \equiv 3 (\mod 5)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[17 \cdot %x + 44 \equiv 333 (\mod 389)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[16 \cdot %x + 1 \equiv 3 (\mod 8)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[5 \cdot %x + 7 \equiv 13 (\mod 29)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[11 \cdot %x + 5 \cdot %x \equiv 64 (\mod 587)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[146467848 \cdot %x \equiv 43698243047256 (\mod 7777777777777777777777777)]]></text>
</part>
<part>
<text hooks="math"><![CDATA[650472472230302 \cdot %x \equiv 1 (\mod 8910581811374)]]></text>
</part>
</parts>
</problem>
<problem>
<text><![CDATA[
Implement the following Python functions. These functions take advantage of the <a href="#c32b1fae4f5d4abb997c85429ae85976">generalized Euclid's lemma</a> to make it possible to generate a random number within a specified range. <b style="color:firebrick;">Your implementations must be extremely efficient, and must handle very large inputs, as shown in the examples below. Implementations that perform exhaustive, exponential-time searches will receive no credit.</b>
]]></text>
<parts>
<part>
<text hooks="math"><![CDATA[
Implement a function <code>closest(t, ks)</code> that takes two arguments: a target integer <code>t</code> and a list of integers <code>ks</code>. The function should return the integer <code>k</code> in <code>ks</code> that is <i>closest</i> to <code>t</code> (i.e., the integer <code>k</code> in <code>ks</code> that minimizes the absolute value of the difference |<code>t</code> %- <code>k</code>| between the two numbers). This will serve as a helper function for subsequent problems in this assignment.
]]></text>
<code class="py"><![CDATA[
>>> closest(5, [1,3,4,9,10])
4
>>> closest(8, [1,3,4,9,10])
9
]]></code>
</part>
<part>
<text hooks="math"><![CDATA[
Implement a function <code>findCoprime(m)</code> that takes a single positive integer argument <code>m</code> and returns an integer <code>b</code> where <code>b</code> \gt 1 and <code>b</code> is coprime with <code>m</code>. Your implementation does not need to return exactly the same answers as you see in the example outputs. However, the output generated by your implementation must be coprime with the input. <b>Hint:</b> <b style="color:green;">use facts about coprime numbers (e.g., <a href="#135ad791f7d2406db11b709d04f03f63">this</a>, <a href="#6e9970794ae24fc6860368be7afe8154">this</a>, <a href="#d748c2e939724ce4a08db35933e7af69">this</a>, <a href="#9e7a019d05154ba0b8e71ad59d57ad0a">this</a>, and/or <a href="#3a48cfd102124a17a72c0eb3e81c8724">this</a>)</b>.
]]></text>
<code class="py"><![CDATA[
>>> findCoprime(10)
7
>>> findCoprime(100)
63
>>> findCoprime(872637825353262)
545398640845789
>>> findCoprime(2**200)
1004336277661868922213726307713226626576376871114245522063361
>>> gcd(findCoprime(2**100000), 2**100000)
1
]]></code>
</part>
<part>
<text hooks="math"><![CDATA[
Implement a function <code>randByIndex(m, i)</code> that takes two positive integer arguments: <code>m</code> represents the upper bound of random numbers to be generated, and <code>i</code> represents an index specifying which random number in a the sequence should be generated. You may assume <code>m</code> \geq 4 and that 1 \leq <code>i</code> \leq <code>m</code> %- 1. The function must return the <code>i</code>th "random" number in a permutation of the numbers {0, ..., <code>m</code> %- 1} by implementing the <a href="#9e7a019d05154ba0b8e71ad59d57ad0c">simplified linear congruential generator</a> with a well-chosen coprime.
]]></text>
<code class="py"><![CDATA[
>>> [randByIndex(10, i) for i in {0,1,2,3,4,5,6,7,8,9}]
[0, 7, 4, 1, 8, 5, 2, 9, 6, 3]
>>> [randByIndex(77, i) for i in range(0,76)]
[ 0, 48, 19, 67, 38, 9, 57, 28, 76, 47, 18, 66,
37, 8, 56, 27, 75, 46, 17, 65, 36, 7, 55, 26,
74, 45, 16, 64, 35, 6, 54, 25, 73, 44, 15, 63,
34, 5, 53, 24, 72, 43, 14, 62, 33, 4, 52, 23,
71, 42, 13, 61, 32, 3, 51, 22, 70, 41, 12, 60,
31, 2, 50, 21, 69, 40, 11, 59, 30, 1, 49, 20,
68, 39, 10, 58]
>>> randByIndex(2**200, 2**99+1)
1004336277661868922213726307713860451876490985814993873666049
]]></code>
<text hooks="math"><![CDATA[
Your implementation does not need to return exactly the same answers as you see in the example outputs. However, the output generated by your implementation must produce a permutation when used in a comprehension, as in the examples, and must work on very large upper bounds and indices.
]]></text>
</part>
</parts>
</problem>
<problem>
<text hooks="math"><![CDATA[
Implement a function <code>probablePrime(m)</code> that takes a single integer argument <code>m</code> where <code>m</code> >= 1. The function should return <code>True</code> if <code>m</code> is probably prime, and <code>False</code> otherwise. Your code should employ the <a href="#458a8c0d2a934388ade43c11e27bb3e5">Fermat primality test</a> by generating some number of random witnesses in the appropriate range and using them to test the primality of <code>m</code>. You will need to determine what is a reasonable number of potential witnesses to test. <b style="color:firebrick;">Implementations that perform an exponentially large exhaustive search, even if the algorithm is <i>mathematically</i> correct, will not earn full credit.</b>
]]></text>
<code class="py"><![CDATA[
>>> probablePrime(31)
True
>>> probablePrime(107)
True
>>> probablePrime(230204771)
True
>>> probablePrime(10738019798475862873464857984759825354679201872)
False
]]></code>
</problem>
<problem>
<text hooks="math"><![CDATA[
Implement a function <code>makePrime(d)</code> that takes a single integer argument <code>d</code> where <code>d</code> >= 1 and returns a probably prime number that has <b>exactly <code>d</code> digits</b>. Your implementation should be sufficiently efficient to produce an output for <code>d</code> = <code>100</code> in a reasonably short amount of time. <b style="color:firebrick;">Implementations that perform an exponentially large exhaustive search, even if the algorithm is <i>mathematically</i> correct, will not earn full credit.</b>
]]></text>
<code class="py"><![CDATA[
>>> makePrime(2)
47
>>> makePrime(100)
3908330587430939367983163094172482420761782436265274101479718696329311615357177668931627057438461519
]]></code>
</problem>
</problems>
</assignment>
</section>
</sheaf>