Introduction
Introduction Statistics Contact Development Disclaimer Help
exercises.tex - libzahl - big integer library
git clone git://git.suckless.org/libzahl
Log
Files
Refs
README
LICENSE
---
exercises.tex (21757B)
---
1 \chapter{Exercises}
2 \label{chap:Exercises}
3
4 % TODO
5 %
6 % All exercises should be group with a chapter
7 %
8 % ▶ Recommended
9 % M Matematically oriented
10 % HM Higher matematical education required
11 % MP Matematical problem solving skills required,
12 % double the rating otherwise; difficult is
13 % very personal
14 %
15 % 00 Immediate
16 % 10 Simple
17 % 20 Medium
18 % 30 Moderately hard
19 % 40 Term project
20 % 50 Research project
21 %
22 % ⁺ High risk of undershoot difficulty
23
24
25 \begin{enumerate}[label=\textbf{\arabic*}.]
26
27
28
29 \item {[$\RHD$\textit{02}]} \textbf{Saturated subtraction}
30
31 Implement the function
32
33 \vspace{-1em}
34 \begin{alltt}
35 void monus(z_t r, z_t a, z_t b);
36 \end{alltt}
37 \vspace{-1em}
38
39 \noindent
40 which calculates $r = a \dotminus b = \max \{ 0,~ a - b \}$.
41
42
43
44 \item {[$\RHD$\textit{10}]} \textbf{Modular powers of 2}
45
46 What is the advantage of using \texttt{zmodpow}
47 over \texttt{zbset} or \texttt{zlsh} in combination
48 with \texttt{zmod}?
49
50
51
52 \item {[\textit{M15}]} \textbf{Convergence of the Lucas Number ratios}
53
54 Find an approximation for
55 $\displaystyle{ \lim_{n \to \infty} \frac{L_{n + 1}}{L_n}}$,
56 where $L_n$ is the $n^{\text{th}}$
57 Lucas Number \psecref{sec:Lucas numbers}.
58
59 \( \displaystyle{
60 L_n \stackrel{\text{\tiny{def}}}{\text{=}} \left \{ \begin{array}{ll}
61 2 & \text{if} ~ n = 0 \\
62 1 & \text{if} ~ n = 1 \\
63 L_{n - 1} + L_{n + 1} & \text{otherwise}
64 \end{array} \right .
65 }\)
66
67
68
69 \item {[\textit{MP12}]} \textbf{Factorisation of factorials}
70
71 Implement the function
72
73 \vspace{-1em}
74 \begin{alltt}
75 void factor_fact(z_t n);
76 \end{alltt}
77 \vspace{-1em}
78
79 \noindent
80 which prints the prime factorisation of $n!$
81 (the $n^{\text{th}}$ factorial). The function shall
82 be efficient for all $n$ where all primes $p \le n$
83 can be found efficiently. You can assume that
84 $n \ge 2$. You should not evaluate $n!$.
85
86
87
88 \item {[\textit{M20}]} \textbf{Reverse factorisation of factorials}
89
90 {\small\textit{You should already have solved
91 ``Factorisation of factorials'' before you solve
92 this problem.}}
93
94 Implement the function
95
96 \vspace{-1em}
97 \begin{alltt}
98 void unfactor_fact(z_t x, z_t *P,
99 unsigned long long int *K, size_t n);
100 \end{alltt}
101 \vspace{-1em}
102
103 \noindent
104 which given the factorsation of $x!$ determines $x$.
105 The factorisation of $x!$ is
106 $\displaystyle{\prod_{i = 1}^{n} P_i^{K_i}}$, where
107 $P_i$ is \texttt{P[i - 1]} and $K_i$ is \texttt{K[i - 1]}.
108
109
110
111 \item {[$\RHD$\textit{MP17}]} \textbf{Factorials inverted}
112
113 Implement the function
114
115 \vspace{-1em}
116 \begin{alltt}
117 void unfact(z_t x, z_t n);
118 \end{alltt}
119 \vspace{-1em}
120
121 \noindent
122 which given a factorial number $n$, i.e. on the form
123 $x! = 1 \cdot 2 \cdot 3 \cdot \ldots \cdot x$,
124 calculates $x = n!^{-1}$. You can assume that
125 $n$ is a perfect factorial number and that $x \ge 1$.
126 Extra credit if you can detect when the input, $n$,
127 is not a factorial number. Such function would of
128 course return an \texttt{int} 1 if the input is a
129 factorial and 0 otherwise, or alternatively 0
130 on success and $-1$ with \texttt{errno} set to
131 \texttt{EDOM} if the input is not a factorial.
132
133
134
135 \item {[\textit{05}]} \textbf{Fast primality test}
136
137 $(x + y)^p \equiv x^p + y^p ~(\text{Mod}~p)$
138 for all primes $p$ and for a few composites $p$,
139 which are know as pseudoprimes. Use this to implement
140 a fast primality tester.
141
142
143
144 \item {[\textit{10}]} \textbf{Fermat primality test}
145
146 $a^{p - 1} \equiv 1 ~(\text{Mod}~p) ~\forall~ 1 < a < p$
147 for all primes $p$ and for a few composites $p$,
148 which are know as pseudoprimes\footnote{If $p$ is composite
149 but passes the test for all $a$, $p$ is a Carmichael
150 number.}. Use this to implement a heuristic primality
151 tester. Try to mimic \texttt{zptest} as much as possible.
152 GNU~MP uses $a = 210$, but you don't have to. ($a$ is
153 called a base.)
154
155
156
157 \item {[\textit{11}]} \textbf{Lucas–Lehmer primality test}
158
159 The Lucas–Lehmer primality test can be used to determine
160 whether a Mersenne numbers $M_n = 2^n - 1$ is a prime (a
161 Mersenne prime). $M_n$ is a prime if and only if
162 $s_{n - 1} \equiv 0 ~(\text{Mod}~M_n)$, where
163
164 \( \displaystyle{
165 s_i = \left \{ \begin{array}{ll}
166 4 & \text{if} ~ i = 0 \\
167 s_{i - 1}^2 - 2 & \text{otherwise}.
168 \end{array} \right .
169 }\)
170
171 \noindent
172 The Lucas–Lehmer primality test requires that $n \ge 3$,
173 however $M_2 = 2^2 - 1 = 3$ is a prime. Implement a version
174 of the Lucas–Lehmer primality test that takes $n$ as the
175 input. For some more fun, when you are done, you can
176 implement a version that takes $M_n$ as the input.
177
178 For improved performance, instead of using \texttt{zmod},
179 you can use the recursive function
180 %
181 \( \displaystyle{
182 k \text{ mod } (2^n - 1) =
183 \left (
184 (k \text{ mod } 2^n) + \lfloor k \div 2^n \rfloor
185 \right ) \text{ mod } (2^n - 1),
186 }\)
187 %
188 where $k \mod 2^n$ is efficiently calculated
189 using \texttt{zand($k$, $2^n - 1$)}. (This optimisation
190 is not part of the difficulty rating of this problem.)
191
192
193
194 \item {[\textit{20}]} \textbf{Fast primality test with bounded perfectio…
195
196 Implement a primality test that is both very fast and
197 never returns \texttt{PROBABLY\_PRIME} for input less
198 than or equal to a preselected number.
199
200
201
202 \item {[\textit{30}]} \textbf{Powers of the golden ratio}
203
204 Implement function that returns $\varphi^n$ rounded
205 to the nearest integer, where $n$ is the input and
206 $\varphi$ is the golden ratio.
207
208
209
210 \item {[\textit{$\RHD$05}]} \textbf{zlshu and zrshu}
211
212 Why does libzahl have
213
214 \vspace{-1em}
215 \begin{alltt}
216 void zlsh(z_t, z_t, size_t);
217 void zrsh(z_t, z_t, size_t);
218 \end{alltt}
219 \vspace{-1em}
220
221 \noindent
222 rather than
223
224 \vspace{-1em}
225 \begin{alltt}
226 void zlsh(z_t, z_t, z_t);
227 void zrsh(z_t, z_t, z_t);
228 void zlshu(z_t, z_t, size_t);
229 void zrshu(z_t, z_t, size_t);
230 \end{alltt}
231 \vspace{-1em}
232
233
234
235 \item {[\textit{$\RHD$M15}]} \textbf{Modular left-shift}
236
237 Implement a function that calculates
238 $2^a \text{ mod } b$, using \texttt{zmod} and
239 only cheap functions. You can assume $a \ge 0$,
240 $b \ge 1$. You can also assume that all
241 parameters are unique pointers.
242
243
244
245 \item {[\textit{$\RHD$08}]} \textbf{Modular left-shift, extended}
246
247 {\small\textit{You should already have solved
248 ``Modular left-shift'' before you solve this
249 problem.}}
250
251 Extend the function you wrote in ``Modular left-shift''
252 to accept negative $b$ and non-unique pointers.
253
254
255
256 \item {[\textit{13}]} \textbf{The totient}
257
258 The totient of $n$ is the number of integer $a$,
259 $0 < a < n$ that are relatively prime to $n$.
260 Implement Euler's totient function $\varphi(n)$
261 which calculates the totient of $n$. Its
262 formula is
263
264 \( \displaystyle{
265 \varphi(n) = |n| \prod_{p \in \textbf{P} : p | n}
266 \left ( 1 - \frac{1}{p} \right ).
267 }\)
268
269 Note that $\varphi(-n) = \varphi(n)$, $\varphi(0) = 0$,
270 and $\varphi(1) = 1$.
271
272
273
274 \item {[\textit{M13}]} \textbf{The totient from factorisation}
275
276 Implement the function
277
278 \vspace{-1em}
279 \begin{alltt}
280 void totient_fact(z_t t, z_t *P,
281 unsigned long long int *K, size_t n);
282 \end{alltt}
283 \vspace{-1em}
284
285 \noindent
286 which calculates the totient $t = \varphi(n)$, where
287 $n = \displaystyle{\prod_{i = 1}^n P_i^{K_i}} > 0$,
288 and $P_i = \texttt{P[i - 1]} \in \textbf{P}$,
289 $K_i = \texttt{K[i - 1]} \ge 1$. All values \texttt{P}
290 are mutually unique. \texttt{P} and \texttt{K} make up
291 the prime factorisation of $n$.
292
293 You can use the following rules:
294
295 \( \displaystyle{
296 \begin{array}{ll}
297 \varphi(1) = 1 & \\
298 \varphi(p) = p - 1 & \text{if } p \in \textbf{P} …
299 \varphi(nm) = \varphi(n)\varphi(m) & \text{if } \gcd(n, m) = 1 …
300 n^a\varphi(n) = \varphi(n^{a + 1}) &
301 \end{array}
302 }\)
303
304
305
306 \item {[\textit{HMP32}]} \textbf{Modular tetration}
307
308 Implement the function
309
310 \vspace{-1em}
311 \begin{alltt}
312 void modtetra(z_t r, z_t b, unsigned long n, z_t m);
313 \end{alltt}
314 \vspace{-1em}
315
316 \noindent
317 which calculates $r = {}^n{}b \text{ mod } m$, where
318 ${}^0{}b = 1$, ${}^1{}b = b$, ${}^2{}b = b^b$,
319 ${}^3{}b = b^{b^b}$, ${}^4{}b = b^{b^{b^b}}$, and so on.
320 You can assume $b > 0$ and $m > 0$. You can also assume
321 \texttt{r}, \texttt{b}, and \texttt{m} are mutually
322 unique pointers.
323
324
325
326 \item {[\textit{13}]} \textbf{Modular generalised power towers}
327
328 {\small\textit{This problem requires a working
329 solution for ``Modular tetration''.}}
330
331 Modify your solution for ``Modular tetration'' to
332 evaluate any expression on the forms
333 $a^b,~a^{b^c},~a^{b^{c^d}},~\ldots \text{ mod } m$.
334
335
336
337 \end{enumerate}
338
339
340
341 \chapter{Solutions}
342 \label{chap:Solutions}
343
344
345 \begin{enumerate}[label=\textbf{\arabic*}.]
346
347 \item \textbf{Saturated subtraction}
348
349 \vspace{-1em}
350 \begin{alltt}
351 void monus(z_t r, z_t a, z_t b)
352 \{
353 zsub(r, a, b);
354 if (zsignum(r) < 0)
355 zsetu(r, 0);
356 \}
357 \end{alltt}
358 \vspace{-1em}
359
360
361 \item \textbf{Modular powers of 2}
362
363 \texttt{zbset} and \texttt{zbit} requires $\Theta(n)$
364 memory to calculate $2^n$. \texttt{zmodpow} only
365 requires $\mathcal{O}(\min \{n, \log m\})$ memory
366 to calculate $2^n \text{ mod } m$. $\Theta(n)$
367 memory complexity becomes problematic for very
368 large $n$.
369
370
371 \item \textbf{Convergence of the Lucas Number ratios}
372
373 It would be a mistake to use bignum, and bigint in particular,
374 to solve this problem. Good old mathematics is a much better solution.
375
376 $$ \lim_{n \to \infty} \frac{L_{n + 1}}{L_n} = \lim_{n \to \infty} \frac…
377
378 $$ \frac{L_{n}}{L_{n - 1}} = \frac{L_{n - 1}}{L_{n - 2}} $$
379
380 $$ \frac{L_{n - 1} + L_{n - 2}}{L_{n - 1}} = \frac{L_{n - 1}}{L_{n - 2}}…
381
382 $$ 1 + \frac{L_{n - 2}}{L_{n - 1}} = \frac{L_{n - 1}}{L_{n - 2}} $$
383
384 $$ 1 + \varphi = \frac{1}{\varphi} $$
385
386 So the ratio tends toward the golden ratio.
387
388
389
390 \item \textbf{Factorisation of factorials}
391
392 Base your implementation on
393
394 \( \displaystyle{
395 n! = \prod_{p~\in~\textbf{P}}^{n} p^{k_p}, ~\text{where}~
396 k_p = \sum_{a = 1}^{\lfloor \log_p n \rfloor} \lfloor np^{-a} \rfloo…
397 }\)
398
399 There is no need to calculate $\lfloor \log_p n \rfloor$,
400 you will see when $p^a > n$.
401
402
403
404 \item \textbf{Reverse factorisation of factorials}
405
406 $\displaystyle{x = \max_{p ~\in~ P} ~ p \cdot f(p, k_p)}$,
407 where $k_p$ is the power of $p$ in the factorisation
408 of $x!$. $f(p, k)$ is defined as:
409
410 \vspace{1em}
411 \hspace{-2.8ex}
412 \begin{minipage}{\linewidth}
413 \begin{algorithmic}
414 \STATE $k^\prime \gets 0$
415 \WHILE{$k > 0$}
416 \STATE $a \gets 0$
417 \WHILE{$p^a \le k$}
418 \STATE $k \gets k - p^a$
419 \STATE $a \gets a + 1$
420 \ENDWHILE
421 \STATE $k^\prime \gets k^\prime + p^{a - 1}$
422 \ENDWHILE
423 \RETURN $k^\prime$
424 \end{algorithmic}
425 \end{minipage}
426 \vspace{1em}
427
428
429
430 \item \textbf{Factorials inverted}
431
432 Use \texttt{zlsb} to get the power of 2 in the
433 prime factorisation of $n$, that is, the number
434 of times $n$ is divisible by 2. If we write $n$ on
435 the form $1 \cdot 2 \cdot 3 \cdot \ldots \cdot x$,
436 every $2^\text{nd}$ factor is divisible by 2, every
437 $4^\text{th}$ factor is divisible by $2^2$, and so on.
438 From calling \texttt{zlsb} we know how many times,
439 $n$ is divisible by 2, but know how many of the factors
440 are divisible by 2, but this can be calculated with
441 the following algorithm, where $k$ is the number
442 times $n$ is divisible by 2:
443
444 \vspace{1em}
445 \hspace{-2.8ex}
446 \begin{minipage}{\linewidth}
447 \begin{algorithmic}
448 \STATE $k^\prime \gets 0$
449 \WHILE{$k > 0$}
450 \STATE $a \gets 0$
451 \WHILE{$2^a \le k$}
452 \STATE $k \gets k - 2^a$
453 \STATE $a \gets a + 1$
454 \ENDWHILE
455 \STATE $k^\prime \gets k^\prime + 2^{a - 1}$
456 \ENDWHILE
457 \RETURN $k^\prime$
458 \end{algorithmic}
459 \end{minipage}
460 \vspace{1em}
461
462 \noindent
463 Note that $2^a$ is efficiently calculated with,
464 \texttt{zlsh}, but it is more efficient to use
465 \texttt{zbset}.
466
467 Now that we know $k^\prime$, the number of
468 factors ni $1 \cdot \ldots \cdot x$ that are
469 divisible by 2, we have two choices for $x$:
470 $k^\prime$ and $k^\prime + 1$. To check which, we
471 calculate $(k^\prime - 1)!!$ (the semifactoral, i.e.
472 $1 \cdot 3 \cdot 5 \cdot \ldots \cdot (k^\prime - 1)$)
473 naïvely and shift the result $k$ steps to the left.
474 This gives us $k^\prime!$. If $x! \neq k^\prime!$, then
475 $x = k^\prime + 1$ unless $n$ is not factorial number.
476 Of course, if $x! = k^\prime!$, then $x = k^\prime$.
477
478
479
480 \item \textbf{Fast primality test}
481
482 If we select $x = y = 1$ we get
483 $2^p \equiv 2 ~(\text{Mod}~p)$. This gives us
484
485 \vspace{-1em}
486 \begin{alltt}
487 enum zprimality
488 ptest_fast(z_t p)
489 \{
490 z_t a;
491 int c = zcmpu(p, 2);
492 if (c <= 0)
493 return c ? NONPRIME : PRIME;
494 zinit(a);
495 zsetu(a, 1);
496 zlsh(a, a, p);
497 zmod(a, a, p);
498 c = zcmpu(a, 2);
499 zfree(a);
500 return c ? NONPRIME : PROBABLY_PRIME;
501 \}
502 \end{alltt}
503 \vspace{-1em}
504
505
506
507 \item \textbf{Fermat primality test}
508
509 Below is a simple implementation. It can be improved by
510 just testing against a fix base, such as $a = 210$, it
511 $t = 0$. It could also do an exhaustive test (all $a$
512 such that $1 < a < p$) if $t < 0$.
513
514 \vspace{-1em}
515 \begin{alltt}
516 enum zprimality
517 ptest_fermat(z_t witness, z_t p, int t)
518 \{
519 enum zprimality rc = PROBABLY_PRIME;
520 z_t a, p1, p3, temp;
521 int c;
522
523 if ((c = zcmpu(p, 2)) <= 0) \{
524 if (!c)
525 return PRIME;
526 if (witness && witness != p)
527 zset(witness, p);
528 return NONPRIME;
529 \}
530
531 zinit(a), zinit(p1), zinit(p3), zinit(temp);
532 zsetu(temp, 3), zsub(p3, p, temp);
533 zsetu(temp, 1), zsub(p1, p, temp);
534
535 zsetu(temp, 2);
536 while (t--) \{
537 zrand(a, DEFAULT_RANDOM, UNIFORM, p3);
538 zadd(a, a, temp);
539 zmodpow(a, a, p1, p);
540 if (zcmpu(a, 1)) \{
541 if (witness)
542 zswap(witness, a);
543 rc = NONPRIME;
544 break;
545 \}
546 \}
547
548 zfree(temp), zfree(p3), zfree(p1), zfree(a);
549 return rc;
550 \}
551 \end{alltt}
552 \vspace{-1em}
553
554
555
556 \item \textbf{Lucas–Lehmer primality test}
557
558 \vspace{-1em}
559 \begin{alltt}
560 enum zprimality
561 ptest_llt(z_t n)
562 \{
563 z_t s, M;
564 int c;
565 size_t p;
566
567 if ((c = zcmpu(n, 2)) <= 0)
568 return c ? NONPRIME : PRIME;
569
570 if (n->used > 1) \{
571 \textcolor{c}{/* \textrm{An optimised implementation would not n…
572 errno = ENOMEM;
573 return (enum zprimality)(-1);
574 \}
575
576 zinit(s), zinit(M), zinit(2);
577
578 p = (size_t)(n->chars[0]);
579 zsetu(s, 1), zsetu(M, 0);
580 zbset(M, M, p, 1), zsub(M, M, s);
581 zsetu(s, 4);
582 zsetu(two, 2);
583
584 p -= 2;
585 while (p--) \{
586 zsqr(s, s);
587 zsub(s, s, two);
588 zmod(s, s, M);
589 \}
590 c = zzero(s);
591
592 zfree(two), zfree(M), zfree(s);
593 return c ? PRIME : NONPRIME;
594 \}
595 \end{alltt}
596
597 $M_n$ is composite if $n$ is composite, therefore,
598 if you do not expect prime-only values on $n$, the
599 performance can be improved by using some other
600 primality test (or this same test if $n$ is a
601 Mersenne number) to first check that $n$ is prime.
602
603
604
605 \item \textbf{Fast primality test with bounded perfection}
606
607 First we select a fast primality test. We can use
608 $2^p \equiv 2 ~(\texttt{Mod}~ p) ~\forall~ p \in \textbf{P}$,
609 as describe in the solution for the problem
610 \textit{Fast primality test}.
611
612 Next, we use this to generate a large list of primes and
613 pseudoprimes. Use a perfect primality test, such as a
614 naïve test or the AKS primality test, to filter out all
615 primes and retain only the pseudoprimes. This is not in
616 runtime so it does not matter that this is slow, but to
617 speed it up, we can use a probabilistic test such the
618 Miller–Rabin primality test (\texttt{zptest}) before we
619 use the perfect test.
620
621 Now that we have a quite large — but not humongous — list
622 of pseudoprimes, we can incorporate it into our fast
623 primality test. For any input that passes the test, and
624 is less or equal to the largest pseudoprime we found,
625 binary search our list of pseudoprime for the input.
626
627 For input, larger than our limit, that passes the test,
628 we can run it through \texttt{zptest} to reduce the
629 number of false positives.
630
631 As an alternative solution, instead of comparing against
632 known pseudoprimes. Find a minimal set of primes that
633 includes divisors for all known pseudoprimes, and do
634 trail division with these primes when a number passes
635 the test. No pseudoprime need to have more than one divisor
636 included in the set, so this set cannot be larger than
637 the set of pseudoprimes.
638
639
640
641 \item \textbf{Powers of the golden ratio}
642
643 This was an information gathering exercise.
644 For $n \ge 2$, $L_n = [\varphi^n]$, where
645 $L_n$ is the $n^\text{th}$ Lucas number.
646
647 \( \displaystyle{
648 L_n \stackrel{\text{\tiny{def}}}{\text{=}} \left \{ \begin{array}{ll}
649 2 & \text{if} ~ n = 0 \\
650 1 & \text{if} ~ n = 1 \\
651 L_{n - 1} + L_{n + 1} & \text{otherwise}
652 \end{array} \right .
653 }\)
654
655 \noindent
656 but for efficiency and briefness, we will use
657 \texttt{lucas} from \secref{sec:Lucas numbers}.
658
659 \vspace{-1em}
660 \begin{alltt}
661 void
662 golden_pow(z_t r, z_t n)
663 \{
664 if (zsignum(n) <= 0)
665 zsetu(r, zcmpi(n, -1) >= 0);
666 else if (!zcmpu(n, 1))
667 zsetu(r, 2);
668 else
669 lucas(r, n);
670 \}
671 \end{alltt}
672 \vspace{-1em}
673
674
675
676 \item \textbf{zlshu and zrshu}
677
678 You are in big trouble, memorywise, of you
679 need to evaluate $2^{2^{64}}$.
680
681
682
683 \item \textbf{Modular left-shift}
684
685 \vspace{-1em}
686 \begin{alltt}
687 void
688 modlsh(z_t r, z_t a, z_t b)
689 \{
690 z_t t, at;
691 size_t s = zbits(b);
692
693 zinit(t), zinit(at);
694 zset(at, a);
695 zsetu(r, 1);
696 zsetu(t, s);
697
698 while (zcmp(at, t) > 0) \{
699 zsub(at, at, t);
700 zlsh(r, r, t);
701 zmod(r, r, b);
702 if (zzero(r))
703 break;
704 \}
705 if (!zzero(a) && !zzero(b)) \{
706 zlsh(r, r, a);
707 zmod(r, r, b);
708 \}
709
710 zfree(at), zfree(t);
711 \}
712 \end{alltt}
713 \vspace{-1em}
714
715 It is worth noting that this function is
716 not necessarily faster than \texttt{zmodpow}.
717
718
719
720 \item \textbf{Modular left-shift, extended}
721
722 The sign of \texttt{b} shall not effect the
723 result. Use \texttt{zabs} to create a copy
724 of \texttt{b} with its absolute value.
725
726
727
728 \item \textbf{The totient}
729
730 \( \displaystyle{
731 \varphi(n)
732 = n \prod_{p \in \textbf{P} : p | n} \left ( 1 - \frac{1}{p} \right )
733 = n \prod_{p \in \textbf{P} : p | n} \left ( \frac{p - 1}{p} \right )
734 }\)
735
736 \noindent
737 So, if we set $a = n$ and $b = 1$, then we iterate
738 of all integers $p$, $2 \le p \le n$. For which $p$
739 that is prime, we set $a \gets a \cdot (p - 1)$ and
740 $b \gets b \cdot p$. After the iteration, $b | a$,
741 and $\varphi(n) = \frac{a}{b}$. However, if $n < 0$,
742 then, $\varphi(n) = \varphi|n|$.
743
744
745
746 \item \textbf{The totient from factorisation}
747
748 \vspace{-1em}
749 \begin{alltt}
750 void
751 totient_fact(z_t t, z_t *P,
752 unsigned long long *K, size_t n)
753 \{
754 z_t a, one;
755 zinit(a), zinit(one);
756 zseti(t, 1);
757 zseti(one, 1);
758 while (n--) \{
759 zpowu(a, P[n], K[n] - 1);
760 zmul(t, t, a);
761 zsub(a, P[n], one);
762 zmul(t, t, a);
763 \}
764 zfree(a), zfree(one);
765 \}
766 \end{alltt}
767 \vspace{-1em}
768
769
770
771 \item \textbf{Modular tetration}
772
773 Let \texttt{totient} be Euler's totient function.
774 It is described in the problem ``The totient''.
775
776 We need two help function: \texttt{tetra(r, b, n)}
777 which calculated $r = {}^n{}b$, and \texttt{cmp\_tetra(a, b, n)}
778 which is compares $a$ to ${}^n{}b$.
779
780 \vspace{-1em}
781 \begin{alltt}
782 void
783 tetra(z_t r, z_t b, unsigned long n)
784 \{
785 zsetu(r, 1);
786 while (n--)
787 zpow(r, b, r);
788 \}
789 \end{alltt}
790 \vspace{-1em}
791
792 \vspace{-1em}
793 \begin{alltt}
794 int
795 cmp_tetra(z_t a, z_t b, unsigned long n)
796 \{
797 z_t B;
798 int cmp;
799
800 if (!n || !zcmpu(b, 1))
801 return zcmpu(a, 1);
802 if (n == 1)
803 return zcmp(a, b);
804 if (zcmp(a, b) >= 0)
805 return +1;
806
807 zinit(B);
808 zsetu(B, 1);
809 while (n) \{
810 zpow(B, b, B);
811 if (zcmp(a, B) < 0) \{
812 zfree(B);
813 return -1;
814 \}
815 \}
816 cmp = zcmp(a, B);
817 zfree(B);
818 return cmp;
819
820 \}
821 \end{alltt}
822 \vspace{-1em}
823
824 \texttt{tetra} can generate unmaintainably huge
825 numbers. Will however only call \texttt{tetra}
826 when this is not the case.
827
828 \vspace{-1em}
829 \begin{alltt}
830 void
831 modtetra(z_t r, z_t b, unsigned long n, z_t m)
832 \{
833 z_t t, temp;
834
835 if (n <= 1) \{
836 if (!n)
837 zsetu(r, zcmpu(m, 1));
838 else
839 zmod(r, b, m);
840 return;
841 \}
842
843 zmod(r, b, m);
844 if (zcmpu(r, 1) <= 0)
845 return;
846
847 zinit(t);
848 zinit(temp);
849
850 t = totient(m);
851 zgcd(temp, b, m);
852
853 if (!zcmpu(temp, 1)) \{
854 modtetra(temp, b, n - 1, t);
855 zmodpow(r, r, temp, m);
856 \} else if (cmp_tetra(t, b, n - 1) > 0) \{
857 temp = tetra(b, n - 1);
858 zpowmod(r, r, temp, m);
859 \} else \{
860 modtetra(temp, b, n - 1, t);
861 zmodpow(temp, r, temp, m);
862 zmodpow(r, r, t, m);
863 zmodmul(r, r, temp, m);
864 \}
865
866 zfree(temp);
867 zfree(t);
868 \}
869 \end{alltt}
870 \vspace{-1em}
871
872
873
874 \item \textbf{Modular generalised power towers}
875
876 Instead of the signature
877
878 \vspace{-1em}
879 \begin{alltt}
880 void modtetra(z_t r, z_t b, unsigned long n, z_t m);
881 \end{alltt}
882 \vspace{-1em}
883
884 \noindent
885 you want to use the signature
886
887 \vspace{-1em}
888 \begin{alltt}
889 void modtower_(z_t r, z_t *a, size_t n, z_t m);
890 \end{alltt}
891 \vspace{-1em}
892
893 Instead of using, \texttt{b} (in \texttt{modtetra}),
894 use \texttt{*a}. At every recursion, instead of
895 passing on \texttt{a}, pass on \texttt{a + 1}.
896
897 The function \texttt{tetra} is modified into
898
899 \vspace{-1em}
900 \begin{alltt}
901 void tower(z_t r, z_t *a, size_t n)
902 \{
903 zsetu(r, 1);
904 while (n--);
905 zpow(r, a[n], r);
906 \}
907 \end{alltt}
908 \vspace{-1em}
909
910 \noindent
911 \texttt{cmp\_tetra} is changed analogously.
912
913 To avoid problems in the evaluation, define
914
915 \vspace{-1em}
916 \begin{alltt}
917 void modtower(z_t r, z_t *a, size_t n, z_t m);
918 \end{alltt}
919 \vspace{-1em}
920
921 \noindent
922 which cuts the power short at the first element
923 of of \texttt{a} that equals 1. For example, if
924 $a = \{2, 3, 4, 5, 1, 2, 3\}$, and $n = 7$
925 ($n = |a|$), then \texttt{modtower}, sets $n = 4$,
926 and effectively $a = \{2, 3, 4, 5\}$. After this
927 \texttt{modtower} calls \texttt{modtower\_}.
928
929
930
931 \end{enumerate}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.