-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patharithmetic.sml
158 lines (126 loc) · 2.91 KB
/
arithmetic.sml
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
151
152
153
154
155
156
157
158
(*
Problems from https://sites.google.com/site/prologsite/prolog-problems/2
Not the most efficient is_prime algorithm, but it'll do here.
*)
structure ProLogArith :> PROBLEMS99 =
struct
(*2.01*)
fun is_prime (n) =
let fun not_divisible(m) =
if n mod m = 0 then false
else if m*m >= n then true
else not_divisible(m+2)
in
if n < 2 then raise Domain
else if 6 mod n = 0 then true
else if n mod 2 = 0 then false
else not_divisible(3)
end
(*2.02*)
fun primes_below (n) =
let fun check (m, acc) =
if m > n then acc
else if is_prime m then check(m+2, acc@[m])
else check(m+2,acc)
in
check (3, [2])
end
fun prime_factors (n) =
let fun spit_factors (lst) =
case lst of
[]=> []
| xs::ys => if n mod xs = 0 then xs::prime_factors(n div xs)
else spit_factors (ys)
in
spit_factors(primes_below(n))
end
(*2.03*)
fun prime_factors_mult (n) =
let
val primes = prime_factors (n)
in
let fun primes_mult (primes_lst, prime, count) =
case primes_lst of
[]=> [[prime, count]]
| xs::ys => if xs = prime then primes_mult (ys, prime, count+1)
else [[prime, count]]@primes_mult (ys, xs, 1)
in
primes_mult (primes, hd primes, 0)
end
end
(*helper function*)
fun is_in (item, lst) =
case lst of
[]=> false
| xs::ys => if xs = item then true
else is_in (item, ys)
(*helper function*)
fun difference (lista, listb) =
case lista of
[]=>[]
| xs::ys => if is_in (xs, listb) then difference (ys, listb)
else xs::difference(ys, listb)
(*2.04*)
fun primes_between (below, upper) =
let
val bp = primes_below (below)
val up = primes_below (upper)
in
difference (up, bp)
end
(*2.05 Goldbach's conjecture*)
(*Wow, this works! Awesome!!!*)
fun goldbach (num) =
let
val possible_primes = primes_below(num)
in
let fun check (N, pp , acc) =
case pp of
[]=> check (N, possible_primes, acc+1)
| xs::ys => if is_prime (acc) andalso (xs+acc = N) then [xs,acc]
else check (N, ys, acc)
in
check (num, possible_primes,2)
end
end
(*2.06*)
fun goldbach_list (lower, upper) =
if lower <=upper then
goldbach (lower) :: goldbach_list(lower+2, upper)
else []
(* 2.07*)
fun gcd (m,n) =
if m=n then m
else if m < n
then gcd(m,n-m)
else gcd(n,m)
(*2.08*)
fun coprime (a, b) =
gcd (a,b) = 1
(*2.09*)
fun phi (m) =
let fun totient_phi (n1, n2) =
if n1<=n2 then
if gcd(n1,n2)=1 then 1 + totient_phi (n1+1,n2)
else 0 + totient_phi (n1+1,n2)
else 0
in
totient_phi(1,m)
end
(*2.10*)
(*helper function*)
fun power (num, n) =
if n = 0 then 1
else num * power(num, n-1)
fun totient_phi (num) =
let fun multiply_phi (lst) =
case lst of
[a,b]::ys => (a-1) * power(a , b -1) * multiply_phi(ys)
| _ => 1
in
multiply_phi(prime_factors_mult(num))
end
(*2.11
Use a timer
*)
end