You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: exams/fermat-primality/index.md
+23-28Lines changed: 23 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ This probabilistic primality test is known as the *Fermat Primality Test*. Note
21
21
*Carmichael numbers*, which are composite yet pass the test for all $a$ relatively prime to the
22
22
respective number, are avoided when testing your implementation of this task.
23
23
24
-
## Pseudo-random Number Generation
24
+
###Pseudo-random Number Generation
25
25
26
26
To generate pseudorandom numbers in a given interval, use
27
27
the *Linear Congruential Generator (LCG)*
@@ -35,11 +35,11 @@ $$
35
35
b' = (b \ \texttt{mod}\, (b^\text{upper} - b^\text{lower})) + b^\text{lower}.
36
36
$$
37
37
38
+
## Haskell
38
39
39
-
Your task is to implement the Fermat Primality Test in Haskell.
40
-
There are two parts to this task: first, implement the LCG, and then the test itself.
40
+
Your task is to implement the Fermat Primality Test in Haskell. Your file should be called `Fermat.hs`, and you should export the function `primality :: Int -> Int -> State LCG Bool`. There are two parts to this task: first, implement the LCG, and then the test itself.
41
41
42
-
## Implementation
42
+
###Implementation
43
43
44
44
The LCG generator is represented as
45
45
```haskell
@@ -84,45 +84,40 @@ False
84
84
True
85
85
```
86
86
87
-
## Hint
87
+
###Hint
88
88
89
89
To prevent overflow of `Int`, compute $a^{p-1}\mod p$ sequentially using
90
90
the identity $a^{k+1}\mod p = a\cdot (a^k\mod p)\mod p$, i.e.,
91
91
sequentially multiplying by $a$ and applying modulo to each partial result.
92
92
93
93
::: details Exam Solution
94
94
```haskell
95
+
moduleFermat (LCG (..), primality) where
96
+
97
+
importControl.Monad
95
98
importControl.Monad.State
96
99
97
-
---- linear congruential generator
98
-
dataLCG=LCGIntIntIntIntderivingShow-- A*x + C mod M
100
+
-- Linear congruential generator
101
+
-- A*x + C mod M
102
+
dataLCG=LCGIntIntIntIntderiving (Show)
103
+
104
+
lcg (LCG a x c m) =
105
+
let y = (a * x + c) `mod` m
106
+
in (y, LCG a y c m)
99
107
100
-
generate::StateLCGInt
101
-
generate =do (LCG a x c m) <- get
102
-
let x' = (a * x + c) `mod` m
103
-
put (LCG a x' c m)
104
-
return x'
108
+
generate = state lcg
105
109
106
-
generate_range::Int->Int->StateLCGInt-- a <= x < b
107
-
generate_range a b =do x <- generate
108
-
let x' = (x `mod` (b-a)) + a
109
-
return x'
110
+
project low high num = (num `mod` (high - low)) + low
110
111
111
-
modulo_power::Int->Int->Int->Int
112
-
modulo_power a n m = iter a n where
113
-
iter b 1= b
114
-
iter b nn = iter (b*a `mod` m) (nn-1)
112
+
generateRange low high = project low high <$> generate
115
113
116
-
fermat_comp::Int->Int->Int
117
-
fermat_comp p b = (modulo_power b (p-1) p)
114
+
moduloPower a n m =iterate (\x -> x * a `mod` m) 1!! n
@@ -109,34 +109,27 @@ The functions `string->list` and `string-split` might be useful to parse the out
109
109
110
110
## Haskell
111
111
112
-
To read multiple lines of input in plain Haskell, we have to tell it how many lines to read.
113
-
Assume that this will be done by first reading a number and then calling `getLine` the desired
114
-
number of times. Implement a function `readInput :: IO [String]` with the following behaviour
115
-
```haskell
116
-
ghci> readInput
117
-
3
118
-
...
119
-
...
120
-
...
121
-
["...","...","..."] <-- this is the function output
122
-
```
123
-
124
-
Your file should have the extension `Minesweeper.hs`.
112
+
Write a Haskell program called `Minesweeper.hs`, which reads the board from standard input. To get all data from standard input as a string, you can call `getContents`. The resulting string can then be split with the `lines` function.
0 commit comments