UNPKG

2.98 kBtext/coffeescriptView Raw
1# Greatest common denominator
2
3
4
5Eval_gcd = ->
6 p1 = cdr(p1)
7 push(car(p1))
8 Eval()
9 p1 = cdr(p1)
10 while (iscons(p1))
11 push(car(p1))
12 Eval()
13 gcd()
14 p1 = cdr(p1)
15
16gcd = ->
17 prev_expanding = expanding
18 save()
19 gcd_main()
20 restore()
21 expanding = prev_expanding
22
23gcd_main = ->
24 expanding = 1
25
26 p2 = pop()
27 p1 = pop()
28
29 if (equal(p1, p2))
30 push(p1)
31 return
32
33 if (isrational(p1) && isrational(p2))
34 push(p1)
35 push(p2)
36 gcd_numbers()
37 return
38
39 if (car(p1) == symbol(ADD) && car(p2) == symbol(ADD))
40 gcd_expr_expr()
41 return
42
43 if (car(p1) == symbol(ADD))
44 gcd_expr(p1)
45 p1 = pop()
46
47 if (car(p2) == symbol(ADD))
48 gcd_expr(p2)
49 p2 = pop()
50
51 if (car(p1) == symbol(MULTIPLY) && car(p2) == symbol(MULTIPLY))
52 gcd_term_term()
53 return
54
55 if (car(p1) == symbol(MULTIPLY))
56 gcd_term_factor()
57 return
58
59 if (car(p2) == symbol(MULTIPLY))
60 gcd_factor_term()
61 return
62
63 # gcd of factors
64
65 if (car(p1) == symbol(POWER))
66 p3 = caddr(p1)
67 p1 = cadr(p1)
68 else
69 p3 = one
70
71 if (car(p2) == symbol(POWER))
72 p4 = caddr(p2)
73 p2 = cadr(p2)
74 else
75 p4 = one
76
77 if (!equal(p1, p2))
78 push(one)
79 return
80
81 # are both exponents numerical?
82
83 if (isnum(p3) && isnum(p4))
84 push(p1)
85 if (lessp(p3, p4))
86 push(p3)
87 else
88 push(p4)
89 power()
90 return
91
92 # are the exponents multiples of eah other?
93
94 push(p3)
95 push(p4)
96 divide()
97
98 p5 = pop()
99
100 if (isnum(p5))
101
102 push(p1)
103
104 # choose the smallest exponent
105
106 if (car(p3) == symbol(MULTIPLY) && isnum(cadr(p3)))
107 p5 = cadr(p3)
108 else
109 p5 = one
110
111 if (car(p4) == symbol(MULTIPLY) && isnum(cadr(p4)))
112 p6 = cadr(p4)
113 else
114 p6 = one
115
116 if (lessp(p5, p6))
117 push(p3)
118 else
119 push(p4)
120
121 power()
122 return
123
124 push(p3)
125 push(p4)
126 subtract()
127
128 p5 = pop()
129
130 if (!isnum(p5))
131 push(one)
132 return
133
134 # can't be equal because of test near beginning
135
136 push(p1)
137
138 if (isnegativenumber(p5))
139 push(p3)
140 else
141 push(p4)
142
143 power()
144
145# in this case gcd is used as a composite function, i.e. gcd(gcd(gcd...
146
147gcd_expr_expr = ->
148 if (length(p1) != length(p2))
149 push(one)
150 return
151
152 p3 = cdr(p1)
153 push(car(p3))
154 p3 = cdr(p3)
155 while (iscons(p3))
156 push(car(p3))
157 gcd()
158 p3 = cdr(p3)
159 p3 = pop()
160
161 p4 = cdr(p2)
162 push(car(p4))
163 p4 = cdr(p4)
164 while (iscons(p4))
165 push(car(p4))
166 gcd()
167 p4 = cdr(p4)
168 p4 = pop()
169
170 push(p1)
171 push(p3)
172 divide()
173 p5 = pop()
174
175 push(p2)
176 push(p4)
177 divide()
178 p6 = pop()
179
180 if (equal(p5, p6))
181 push(p5)
182 push(p3)
183 push(p4)
184 gcd()
185 multiply()
186 else
187 push(one)
188
189gcd_expr = (p) ->
190 p = cdr(p)
191 push(car(p))
192 p = cdr(p)
193 while (iscons(p))
194 push(car(p))
195 gcd()
196 p = cdr(p)
197
198gcd_term_term = ->
199 push(one)
200 p3 = cdr(p1)
201 while (iscons(p3))
202 p4 = cdr(p2)
203 while (iscons(p4))
204 push(car(p3))
205 push(car(p4))
206 gcd()
207 multiply()
208 p4 = cdr(p4)
209 p3 = cdr(p3)
210
211gcd_term_factor = ->
212 push(one)
213 p3 = cdr(p1)
214 while (iscons(p3))
215 push(car(p3))
216 push(p2)
217 gcd()
218 multiply()
219 p3 = cdr(p3)
220
221gcd_factor_term = ->
222 push(one)
223 p4 = cdr(p2)
224 while (iscons(p4))
225 push(p1)
226 push(car(p4))
227 gcd()
228 multiply()
229 p4 = cdr(p4)
230
231