#lang scribble/manual @(require (for-label racket/flonum racket/fixnum racket/unsafe/ops racket/require racket/base (only-in typed/racket/base Integer Exact-Rational Boolean Listof Natural U List Positive-Integer) math) scribble/extract scribble/eval scribble/base scribble/manual racket/sandbox racket/math "utils.rkt") @(define untyped-eval (make-untyped-math-eval)) @interaction-eval[#:eval untyped-eval (require racket/list racket/function)] @(define math-style tt) @title[#:tag "number-theory"]{Number Theory} @(author-jens-axel) @defmodule[math/number-theory] @local-table-of-contents[] @; ---------------------------------------- @section[#:tag "congruences"]{Congruences and Modular Arithmetic} @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Divisor"]{Divisor}} @defproc[(divides? [m Integer] [n Integer]) Boolean]{ Returns @racket[#t] if @racket[m] divides @racket[n], @racket[#f] otherwise. Formally, an integer @racket[m] divides an integer @racket[n] when there exists a unique integer @racket[k] such that @racket[(* m k) = n]. @examples[#:eval untyped-eval (divides? 2 9) (divides? 2 8)] Note that @racket[0] cannot divide anything: @interaction[#:eval untyped-eval (divides? 0 5) (divides? 0 0)] Practically, if @racket[(divides? m n)] is @racket[#t], then @racket[(/ n m)] will return an integer and will not raise @racket[exn:fail:contract:divide-by-zero]. } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/B%C3%A9zout's_identity"]{Bezout's Identity}} @defproc[(bezout [a Integer] [b Integer] [c Integer] ...) (Listof Integer)]{ Given integers @racket[a b c ...] returns a list of integers @racket[(list u v w ...)] such that @racket[(gcd a b c ...) = (+ (* a u) (* b v) (* c w) ...)]. @examples[#:eval untyped-eval (bezout 6 15) (+ (* -2 6) (* 1 15)) (gcd 6 15)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Coprime"]{Coprime}} @defproc[(coprime? [a Integer] [b Integer] ...) Boolean]{ Returns @racket[#t] if the integers @racket[a b ...] are coprime. Formally, a set of integers is considered coprime (also called relatively prime) if their greatest common divisor is 1. @examples[#:eval untyped-eval (coprime? 2 6 15)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Pairwise_coprime"]{Pairwise Coprime}} @defproc[(pairwise-coprime? [a Integer] [b Integer] ...) Boolean]{ Returns @racket[#t] if the integers @racket[a b ...] are @italic{pairwise} coprime, meaning that each adjacent pair of integers is coprime. The numbers 2, 6 and 15 are coprime, but not @italic{pairwise} coprime, because 2 and 6 share the factor 3: @interaction[#:eval untyped-eval (pairwise-coprime? 2 6 15)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Chinese_remainder_theorem"]{Chinese Remainder Theorem}} @defproc[(solve-chinese [as (Listof Integer)] [ns (Listof Integer)]) Natural]{ Given a length-@racket[k] list of integers @racket[as] and a length-@racket[k] list of coprime moduli @racket[ns], @racket[(solve-chinese as ns)] returns the least natural number @racket[x] that is a solution to the equations @racketblock[x = #,(elem @racket[a] @subscript{1}) #,(elem "(mod " @racket[n] @subscript{1} ")") ... x = #,(elem @racket[a] @subscript{@racket[k]}) #,(elem "(mod " @racket[x] @subscript{@racket[k]} ")")] The solution @racket[x] is less than @racket[(* #,(elem @racket[n] @subscript{1}) ... #,(elem @racket[n] @subscript{@racket[k]}))]. The moduli @racket[ns] must all be positive. What is the least number @racket[x] that when divided by 3 leaves a remainder of 2, when divided by 5 leaves a remainder of 3, and when divided by 7 leaves a remainder of 2? @interaction[#:eval untyped-eval (solve-chinese '(2 3 2) '(3 5 7))] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Quadratic_residue"]{Quadratic Residue}} @defproc[(quadratic-residue? [a Integer] [n Integer]) Boolean]{ Returns @racket[#t] if @racket[a] is a quadratic residue modulo @racket[n], otherwise @racket[#f]. The modulus @racket[n] must be positive, and @racket[a] must be nonnegative. Formally, @racket[a] is a quadratic residue modulo @racket[n] if there exists a number @racket[x] such that @racket[(* x x) = a] (mod @racket[n]). In other words, @racket[(quadratic-residue? a n)] is @racket[#t] when @racket[a] is a perfect square modulo @racket[n]. @examples[#:eval untyped-eval (quadratic-residue? 0 4) (quadratic-residue? 1 4) (quadratic-residue? 2 4) (quadratic-residue? 3 4)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Legendre_symbol"]{Legendre Symbol}} @defproc[(quadratic-character [a Integer] [p Integer]) (U -1 0 1)]{ Returns the value of the quadratic character modulo the prime @racket[p]. That is, for a non-zero @racket[a] the number @racket[1] is returned when @racket[a] is a quadratic residue, and @racket[-1] is returned when @racket[a] is a non-residue. If @racket[a] is zero, then @racket[0] is returned. If @racket[a] is negative or @racket[p] is not positive, @racket[quadratic-character] raises an error. If @racket[p] is not prime, @racket[(quadratic-character a p)] is indeterminate. This function is also known as the @emph{Legendre symbol}. @interaction[#:eval untyped-eval (quadratic-character 0 5) (quadratic-character 1 5) (quadratic-character 2 5) (quadratic-character 3 5)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Modular_multiplicative_inverse"]{Multiplicative Inverse}} @defproc[(modular-inverse [a Integer] [n Integer]) Natural]{ Returns the inverse of @racket[a] modulo @racket[n] if @racket[a] and @racket[n] are coprime, otherwise raises an error. The modulus @racket[n] must be positive, and @racket[a] must be nonzero. Formally, if @racket[a] and @racket[n] are coprime, @racket[b = (modular-inverse a n)] is the unique natural number less than @racket[n] such that @racket[(* a b) = 1] (mod @racket[n]). @interaction[#:eval untyped-eval (modular-inverse 2 5) (modulo (* 2 3) 5)] } @defproc[(modular-expt [a Integer] [b Integer] [n Integer]) Natural]{ Computes @racket[(modulo (expt a b) n)], but much more efficiently. The modulus @racket[n] must be positive, and the exponent @racket[b] must be nonnegative. @examples[#:eval untyped-eval (modulo (expt -6 523) 19) (modular-expt -6 523 19) (modular-expt 9 158235208 19) (eval:alts (code:line (code:comment "don't try this at home!") (modulo (expt 9 158235208) 19)) (eval:result @racketresultfont{4})) ] } @subsection[#:tag "modular"]{Parameterized Modular Arithmetic} @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Modular_arithmetic"]{Modular Arithmetic}} The @racketmodname[math/number-theory] library supports modular arithmetic parameterized on a current modulus. For example, the code @racketblock[(with-modulus n ((modexpt a b) . mod= . c))] corresponds with the mathematical statement @italic{a}@superscript{@italic{b}} = @italic{c} (mod @italic{n}). The current modulus is stored in a parameter that, for performance reasons, can only be set using @racket[with-modulus]. (The basic modular operators cache parameter reads, and this restriction guarantees that the cached values are current.) @defform[(with-modulus n body ...) #:contracts ([n Integer])]{ Alters the current modulus within the dynamic extent of @racket[body]. The expression @racket[n] must evaluate to a positive integer. By default, the current modulus is @racket[1], meaning that every modular arithmetic expression that does not raise an error returns @racket[0]. } @defproc[(current-modulus) Positive-Integer]{ Returns the current modulus. @examples[#:eval untyped-eval (current-modulus) (with-modulus 5 (current-modulus))] } @defproc[(mod [x Exact-Rational]) Natural]{ Converts a rational number @racket[x] to a natural number less than the current modulus. If @racket[x] is an integer, this is equivalent to @racket[(modulo x n)]. If @racket[x] is a fraction, an integer input is generated by multiplying its numerator by its denominator's modular inverse. @examples[#:eval untyped-eval (with-modulus 7 (mod (* 218 7))) (with-modulus 7 (mod 3/2)) (with-modulus 7 (mod/ 3 2)) (with-modulus 7 (mod 3/7))] } @deftogether[(@defproc[(mod+ [a Integer] ...) Natural] @defproc[(mod* [a Integer] ...) Natural])]{ Equivalent to @racket[(modulo (+ a ...) (current-modulus))] and @racket[(modulo (* a ...) (current-modulus))], respectively, but generate smaller intermediate values. } @deftogether[(@defproc[(modsqr [a Integer]) Natural] @defproc[(modexpt [a Integer] [b Integer]) Natural])]{ Equivalent to @racket[(mod* a a)] and @racket[(modular-expt a b (current-modulus))], respectively. } @defproc[(mod- [a Integer] [b Integer] ...) Natural]{ Equivalent to @racket[(modulo (- a b ...) (current-modulus))], but generates smaller intermediate values. Note that @racket[(mod- a) = (mod (- a))]. } @defproc[(mod/ [a Integer] [b Integer] ...) Natural]{ Divides @racket[a] by @racket[(* b ...)], by multiplying @racket[a] by the multiplicative inverse of @racket[(* b ...)]. The one-argument variant returns the modular inverse of @racket[a]. Note that @racket[(mod/ a b ...)] is @bold{not} equivalent to @racket[(modulo (/ a b ...) (current-modulus))]; see @racket[mod=] for a demonstration. } @deftogether[(@defproc[(mod= [a Integer] [b Integer] ...) Boolean] @defproc[(mod< [a Integer] [b Integer] ...) Boolean] @defproc[(mod<= [a Integer] [b Integer] ...) Boolean] @defproc[(mod> [a Integer] [b Integer] ...) Boolean] @defproc[(mod>= [a Integer] [b Integer] ...) Boolean])]{ Each of these is equivalent to @racket[(op (mod a) (mod b) ...)], where @racket[op] is the corresponding numeric comparison function. Additionally, when given one argument, the inequality tests always return @racket[#t]. Suppose we wanted to know why 17/4 = 8 (mod 15), but 51/12 (mod 15) is undefined, even though normally 51/12 = 17/4. In code, @interaction[#:eval untyped-eval (with-modulus 15 (mod/ 17 4)) (/ 51 12) (with-modulus 15 (mod/ 51 12))] We could try to divide by brute force: find, modulo 15, all the numbers @racket[a] for which @racket[(mod* a 4)] is @racket[17], then find all the numbers @racket[b] for which @racket[(mod* a 12)] is @racket[51]. @interaction[#:eval untyped-eval (with-modulus 15 (for/list ([a (in-range 15)] #:when (mod= (mod* a 4) 17)) a)) (with-modulus 15 (for/list ([b (in-range 15)] #:when (mod= (mod* b 12) 51)) b))] So the problem isn't that @racket[b] doesn't exist, it's that @racket[b] isn't @italic{unique}. } @; ---------------------------------------- @section[#:tag "primes"]{Primes} @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Prime_number"]{Prime Number}} @defproc[(prime? [z Integer]) Boolean]{ Returns @racket[#t] if @racket[z] is a prime, @racket[#f] otherwise. Formally, an integer @racket[z] is prime when the only positive divisors of @racket[z] are @racket[1] and @racket[(abs z)]. The positive primes below 20 are: @interaction[#:eval untyped-eval (filter prime? (range 1 21))] The corresponding negative primes are: @interaction[#:eval untyped-eval (filter prime? (range 1 -21 -1))] } @defproc[(odd-prime? [z Integer]) Boolean]{ Returns @racket[#t] if @racket[z] is a odd prime, @racket[#f] otherwise. @interaction[#:eval untyped-eval (odd-prime? 2) (odd-prime? 3)] } @defproc[(nth-prime [n Integer]) Natural]{ Returns the @racket[n]th positive prime; @racket[n] must be nonnegative. @interaction[#:eval untyped-eval (nth-prime 0) (nth-prime 1) (nth-prime 2)] } @defproc[(random-prime [n Integer]) Natural]{ Returns a random prime smaller than @racket[n], which must be greater than @racket[2]. The function @racket[random-prime] picks random numbers below @racket[n] until a prime is found. @interaction[#:eval untyped-eval (random-prime 10) (random-prime 10) (random-prime 10)] } @defproc[(next-prime [z Integer]) Integer]{ Returns the first prime larger than @racket[z]. @interaction[#:eval untyped-eval (next-prime 4) (next-prime 5)] } @defproc[(prev-prime [z Integer]) Integer]{ Returns the first prime smaller than @racket[z]. @interaction[#:eval untyped-eval (prev-prime 4) (prev-prime 5)] } @defproc[(next-primes [z Integer] [n Integer]) (Listof Integer)]{ Returns list of the next @racket[n] primes larger than @racket[z]; @racket[n] must be nonnegative. @interaction[#:eval untyped-eval (next-primes 2 4)] } @defproc[(prev-primes [z Integer] [n Integer]) (Listof Integer)]{ Returns list of the next @racket[n] primes smaller than @racket[z]; @racket[n] must be nonnegative. @interaction[#:eval untyped-eval (prev-primes 13 4)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Integer_factorization"]{Integer Factorization}} @defproc[(factorize [n Natural]) (Listof (List Natural Natural))]{ Returns the factorization of a natural number @racket[n]. The factorization consists of a list of corresponding primes and exponents. The primes will be in ascending order. The prime factorization of 600 = 2^3 * 3^1 * 5^2: @interaction[#:eval untyped-eval (factorize 600)] } @defproc[(defactorize [f (Listof (List Natural Natural))]) Natural]{ Returns the natural number, whose factorization is given by @racket[f]. The factorization @racket[f] is represented as described in @racket[factorize]. @interaction[#:eval untyped-eval (defactorize '((2 3) (3 1) (5 2)))] } @defproc[(divisors [z Integer]) (Listof Natural)]{ Returns a list of all positive divisors of the integer @racket[z]. The divisors appear in ascending order. @interaction[#:eval untyped-eval (divisors 120) (divisors -120)] } @defproc[(prime-divisors [z Natural]) (Listof Natural)]{ Returns a list of all positive prime divisors of the integer @racket[z]. The divisors appear in ascending order. @interaction[#:eval untyped-eval (prime-divisors 120)] } @defproc[(prime-exponents [z Natural]) (Listof Natural)]{ Returns a list of the exponents of in a factorization of the integer @racket[z]. @interaction[#:eval untyped-eval (define z (* 2 2 2 3 5 5)) (prime-divisors z) (prime-exponents z)] } @; ---------------------------------------- @section[#:tag "roots"]{Roots} @defproc[(integer-root [n Natural] [m Natural]) Natural]{ Returns the @racket[m]th integer root of @racket[n]. This is the largest integer @racket[r] such that @racket[(expt r m) <= n]. @interaction[#:eval untyped-eval (integer-root (expt 3 4) 4) (integer-root (+ (expt 3 4) 1) 4)] } @defproc[(integer-root/remainder [n Natural] [m Natural]) (values Natural Natural)]{ Returns two values. The first, @racket[r], is the @racket[m]th integer root of @racket[n]. The second is @racket[n-r^m]. @interaction[#:eval untyped-eval (integer-root/remainder (expt 3 4) 4) (integer-root/remainder (+ (expt 3 4) 1) 4)] } @; ---------------------------------------- @section[#:tag "powers"]{Powers} @defproc[(max-dividing-power [a Integer] [b Integer]) Natural]{ Returns the largest exponent, @racket[n], of a power with base @racket[a] that divides @racket[b]. That is, @racket[(expt a n)] divides @racket[b] but @racket[(expt a (+ n 1))] does not divide @racket[b]. @interaction[#:eval untyped-eval (max-dividing-power 3 (expt 3 4)) (max-dividing-power 3 5)] } @defproc[(perfect-power [m Integer]) (U (List Natural Natural) #f)]{ If @racket[m] is a perfect power, a list with two elements @racket[b] and @racket[n] such that @racket[(expt b n) = m] is returned, otherwise @racket[#f] is returned. @interaction[#:eval untyped-eval (perfect-power (expt 3 4)) (perfect-power (+ (expt 3 4) 1))] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Perfect_power"]{Perfect Power}} @defproc[(perfect-power? [m Integer]) Boolean]{ Returns @racket[#t] if @racket[m] is a perfect power, otherwise @racket[#f]. @interaction[#:eval untyped-eval (perfect-power? (expt 3 4)) (perfect-power? (+ (expt 3 4) 1))] } @defproc[(prime-power [m Natural]) (U (List Natural Natural) #f)]{ If @racket[m] is a power of the form @racket[(expt p n)] where @racket[p] is prime, then a list with the prime and the exponent is returned, otherwise @racket[#f] is returned. @interaction[#:eval untyped-eval (prime-power (expt 3 4)) (prime-power (expt 6 4))] } @defproc[(prime-power? [m Natural]) Boolean]{ Returns @racket[#t] if @racket[m] is a prime power, otherwise @racket[#f]. @interaction[#:eval untyped-eval (prime-power? (expt 3 4)) (prime-power? (expt 6 4)) (prime-power? 1) (prime-power? 0)] } @defproc[(odd-prime-power? [m Natural]) Boolean]{ Returns @racket[#t] if @racket[m] is a power of an odd prime, otherwise @racket[#f]. @interaction[#:eval untyped-eval (odd-prime-power? (expt 2 4)) (odd-prime-power? (expt 3 4)) (odd-prime-power? (expt 15 4))] } @defproc[(as-power [m Positive-Integer]) (values Natural Natural)]{ Returns two values @racket[b] and @racket[n] such that @racket[m = (expt b n)] and @racket[n] is maximal. @interaction[#:eval untyped-eval (as-power (* (expt 2 4) (expt 3 4))) (expt 6 4) (* (expt 2 4) (expt 3 4)) (as-power (* (expt 2 4) (expt 3 5)))] } @defproc[(perfect-square [m Natural]) (U Natural #f)]{ Returns @racket[(sqrt m)] if @racket[m] is perfect square, otherwise @racket[#f]. @interaction[#:eval untyped-eval (perfect-square 9) (perfect-square 10)] } @; ---------------------------------------- @section[#:tag "multiplicative"]{Multiplicative Functions} The functions in this section are @deftech{multiplicative}. In number theory, a multiplicative function is a function @racket[f] such that @racket[(f a b) = (* (f a) (f b))] for all coprime natural numbers @racket[a] and @racket[b]. @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Euler%27s_totient_function"]{Euler's Totient}} @defproc[(totient [n Natural]) Natural]{ Returns the number of integers from 1 to @racket[n] that are coprime with @racket[n]. This function is known as Eulers totient or phi function. @interaction[#:eval untyped-eval (totient 9) (length (filter (curry coprime? 9) (range 10)))] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/M%C3%B6bius_function"]{Moebius Function}} @defproc[(moebius-mu [n Natural]) (U -1 0 1)]{ Returns: @itemlist[@item{@racket[1] if @racket[n] is a product of an even number of primes} @item{@racket[-1] if @racket[n] is a product of an odd number of primes} @item{@racket[0] if @racket[n] has a multiple prime factor}] @interaction[#:eval untyped-eval (moebius-mu (* 2 3 5)) (moebius-mu (* 2 3 5 7)) (moebius-mu (* 2 2 3 5 7))] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Divisor_function"]{Divisor Function}} @defproc[(divisor-sum [n Natural] [k Natural]) Natural]{ Returns sum of the @racket[k]th powers of all divisors of @racket[n]. @interaction[#:eval untyped-eval (divisor-sum 12 2) (apply + (map sqr (divisors 12)))] } @margin-note{OEIS: @hyperlink["http://oeis.org/A001222"]{Big Omega}} @defproc[(prime-omega [n Natural]) natural?]{ Counting multiplicities the number of prime factors of @racket[n] is returned. Note: The function @racket[prime-omega] is multiplicative. @interaction[#:eval untyped-eval (prime-omega (* 2 2 2 3 3 5))] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Von_Mangoldt_function"]{Von Mangoldt Function}} @defproc[(mangoldt-lambda [n Natural]) Real]{ The von Mangoldt function. If @racket[n=p^k] for a prime @racket[p] and an integer @racket[k>=1] then @racket[(log n)] is returned. Otherwise 0 is returned. @interaction[#:eval untyped-eval (mangoldt-lambda (* 3 3)) (log 3)] } @; ---------------------------------------- @section[#:tag "number-sequences"]{Number Sequences} @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Bernoulli_number"]{Bernoulli Number}} @defproc[(bernoulli [n Integer]) Exact-Rational]{ Returns the @racket[n]th Bernoulli number; @racket[n] must be nonnegative. @interaction[#:eval untyped-eval (map bernoulli (range 9))] Note that these are the @italic{first} Bernoulli numbers, since @racket[(bernoulli 1) = -1/2]. } @margin-note{MathWorld: @hyperlink["http://mathworld.wolfram.com/EulerianNumber.html"]{Eulerian Number}} @defproc[(eulerian-number [n Integer] [k Integer]) Natural]{ Returns the Eulerian number @math-style{}; both arguments must be nonnegative. @interaction[#:eval untyped-eval (eulerian-number 5 2)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Fibonacci_number"]{Fibonacci Number}} @defproc[(fibonacci [n Integer]) Natural]{ Returns the @racket[n]th Fibonacci number; @racket[n] must be nonnegative. The ten first Fibonacci numbers. @interaction[#:eval untyped-eval (map fibonacci (range 10))] } @defproc[(fibonacci/mod [n Integer] [m Integer]) Natural]{ Returns the @racket[n]th Fibonacci number modulo @racket[m]; @racket[n] must be nonnegative and @racket[m] must be positive. The ten first Fibonacci numbers modulo 5. @interaction[#:eval untyped-eval (map (λ (n) (fibonacci/mod n 5)) (range 10))] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Farey_sequence"]{Farey Sequence}} @defproc[(farey [n Integer]) (Listof Exact-Rational)]{ Returns a list of the numbers in the @racket[n]th Farey sequence; @racket[n] must be positive. The @racket[n]th Farey sequence is the sequence of all completely reduced rational numbers from 0 to 1 which denominators are less than or equal to @racket[n]. @interaction[#:eval untyped-eval (farey 1) (farey 2) (farey 3)] } @margin-note{MathWorld: @hyperlink["http://mathworld.wolfram.com/TangentNumber.html"]{Tangent Number}} @defproc[(tangent-number [n Integer]) Integer]{ Returns the @racket[n]th tangent number; @racket[n] must be nonnegative. @interaction[#:eval untyped-eval (tangent-number 1) (tangent-number 2) (tangent-number 3)] } @; ---------------------------------------- @section[#:tag "combinatorics"]{Combinatorics} @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Factorial"]{Factorial}} @defproc[(factorial [n Integer]) Natural]{ Returns the factorial of @racket[n], which must be nonnegative. The factorial of @racket[n] is the number @racket[(* n (- n 1) (- n 2) ... 1)]. @interaction[#:eval untyped-eval (factorial 3) (factorial 0)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Binomial_coefficient"]{Binomial Coefficient}} @defproc[(binomial [n Integer] [k Integer]) Natural]{ Returns the number of ways to choose a @italic{set} of @racket[k] items from a set of @racket[n] items; i.e. the order of the @racket[k] items is not significant. Both arguments must be nonnegative. When @racket[k > n], @racket[(binomial n k) = 0]. Otherwise, @racket[(binomial n k)] is equivalent to @racket[(/ (factorial n) (factorial k) (factorial (- n k)))], but computed more quickly. @interaction[#:eval untyped-eval (binomial 5 3)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Permutation#Permutations_in_combinatorics"]{ Permutations}} @defproc[(permutations [n Integer] [k Integer]) Natural]{ Returns the number of ways to choose a @italic{sequence} of @racket[k] items from a set of @racket[n] items; i.e. the order of the @racket[k] items is significant. Both arguments must be nonnegative. When @racket[k > n], @racket[(permutations n k) = 0]. Otherwise, @racket[(permutations n k)] is equivalent to @racket[(/ (factorial n) (factorial (- n k)))]. @interaction[#:eval untyped-eval (permutations 5 3)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Multinomial_theorem#Multinomial_coefficients"]{Multinomial Coeffecient}} @defproc[(multinomial [n Integer] [ks (Listof Integer)]) Natural]{ A generalization of @racket[binomial] to multiple sets of choices; i.e. @racket[(multinomial n (list k0 k1))] is the number of ways to choose a set of @racket[k0] items and a set of @racket[k1] items from a set of @racket[n] items. All arguments must be nonnegative. When @racket[(apply + ks) = n], this is equivalent to @racket[(apply / (factorial n) (map factorial ks))]. Otherwise, it returns @racket[0]. @interaction[#:eval untyped-eval (multinomial 5 3 2)] } @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Partition_(number_theory)"]{Partition}} @defproc[(partition-count [n Integer]) Natural]{ Returns the number of partitions of @racket[n], which must be nonnegative. A partition of a positive integer @racket[n] is a way of writing @racket[n] as a sum of positive integers. The number 3 has the partitions @racket[(+ 1 1 1)], @racket[(+ 1 2)] and @racket[(+ 3)]. @interaction[#:eval untyped-eval (partition-count 3) (partition-count 4)] } @; ---------------------------------------- @section[#:tag "special_numbers"]{Special Numbers} @subsection{Polygonal Numbers} @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Polygonal_number"]{Polygonal Number}} @deftogether[ (@defproc[(triangle-number? [n Natural]) Boolean] @defproc[(square-number? [n Natural]) Boolean] @defproc[(pentagonal-number? [n Natural]) Boolean] @defproc[(hexagonal-number? [n Natural]) Boolean] @defproc[(heptagonal-number? [n Natural]) Boolean] @defproc[(octagonal-number? [n Natural]) Boolean])]{ These functions check whether the input is a polygonal number of the types triangle, square, pentagonal, hexagonal, heptagonal and octogonal respectively. } @deftogether[ (@defproc[(triangle-number [n Natural]) Natural] @defproc[(sqr [n Natural]) Natural] @defproc[(pentagonal-number [n Natural]) Natural] @defproc[(hexagonal-number [n Natural]) Natural] @defproc[(heptagonal-number [n Natural]) Natural] @defproc[(octagonal-number [n Natural]) Natural])]{ These functions return the @racket[n]th polygonal number of the corresponding type of polygonal number. } @; ---------------------------------------- @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Mediant_(mathematics)"]{Mediant}} @section[#:tag "fractions"]{Fractions} @defproc[(mediant [x Exact-Rational] [y Exact-Rational]) Exact-Rational]{ Computes the @racket[mediant] of the numbers @racket[x] and @racket[y]. The mediant of two fractions @math-style{p/q} and @math-style{r/s} in their lowest term is the number @math-style{(p+r)/(q+s)}. @interaction[#:eval untyped-eval (mediant 1/2 5/6)] } @; ---------------------------------------- @section[#:tag "quadratics"]{The Quadratic Equation} @defproc[(quadratic-solutions [a Real] [b Real] [c Real]) (Listof Real)]{ Returns a list of all real solutions to the equation @math-style{a x^2 + b x +c = 0}. @interaction[#:eval untyped-eval (quadratic-solutions 1 0 -1) (quadratic-solutions 1 2 1) (quadratic-solutions 1 0 1)] } @defproc[(quadratic-integer-solutions [a Real] [b Real] [c Real]) (Listof Integer)]{ Returns a list of all integer solutions to the equation @math-style{a x^2 + b x +c = 0}. @interaction[#:eval untyped-eval (quadratic-integer-solutions 1 0 -1) (quadratic-integer-solutions 1 0 -2)] } @defproc[(quadratic-natural-solutions [a Real] [b Real] [c Real]) (Listof Natural)]{ Returns a list of all natural solutions to the equation @math-style{a x^2 + b x +c = 0}. @interaction[#:eval untyped-eval (quadratic-natural-solutions 1 0 -1) (quadratic-natural-solutions 1 0 -2)] } @; ---------------------------------------- @section[#:tag "primitive_roots"]{The group Zn and Primitive Roots} @margin-note{Wikipedia: @hyperlink["http://en.wikipedia.org/wiki/Multiplicative_group_of_integers_modulo_n"]{ The Group Zn}} The numbers @math-style{0, 1, ..., n-1} with addition and multiplication modulo @racket[n] is a ring called @math-style{Zn}. The group of units in @math-style{Zn} with respect to multiplication modulo @racket[n] is called @math-style{Un}. The order of an element @math-style{x} in @math-style{Un} is the least @math-style{k>0} such that @math-style{x^k=1 mod n}. A generator the group @math-style{Un} is called a @emph{primitive root} modolo @racket[n]. Note that @math-style{g} is a primitive root if and only if @math-style{order(g)=phi(n)}, where @math-style{phi} is Eulers totient. A group with a generator is called @emph{cyclic}. @defproc[(unit-group [n Integer]) (Listof Positive-Integer)]{ Returns a list of all elements of @math-style{Un}, the unit group modulo @racket[n]. The modulus @racket[n] must be positive. @interaction[#:eval untyped-eval (unit-group 5) (unit-group 6)] } @defproc[(order [x Integer] [n Integer]) Positive-Integer]{ Returns the order of @racket[x] in the group @math-style{Un}; both arguments must be positive. If @racket[x] and @racket[n] are not coprime, @racket[(order x n)] raises an error. @interaction[#:eval untyped-eval (order 2 5) (order 2 6)] } @defproc[(orders [n Integer]) (Listf Positive-Integer)]{ Returns a list @racket[(list (order x0 n) (order x1 n) ...)] where @racket[x0], @racket[x1], ... are the elements of @math-style{Un}. The modulus @racket[n] must be positive. @interaction[#:eval untyped-eval (orders 5) (map (curryr order 5) (unit-group 5))] } @defproc[(primitive-root? [x Integer] [n Integer]) Boolean]{ Returns @racket[#t] if the element @racket[x] in @math-style{Un} is a primitive root modulo @racket[n], otherwise @racket[#f] is returned. An error is signaled if @racket[x] is not a member of @math-style{Un}. Both arguments must be positive. @interaction[#:eval untyped-eval (primitive-root? 1 5) (primitive-root? 2 5) (primitive-root? 5 5)] } @defproc[(exists-primitive-root? [n Integer]) Boolean]{ Returns @racket[#t] if the group @math-style{Un} has a primitive root (i.e. it is cyclic), otherwise @racket[#f] is returned. In other words, @racket[#t] is returned if @racket[n] is one of @math-style{1, 2, 4, p^e, 2*p^e} where @math-style{p} is an odd prime, and @racket[#f] otherwise. The modulus @racket[n] must be positive. @interaction[#:eval untyped-eval (exists-primitive-root? 5) (exists-primitive-root? 6) (exists-primitive-root? 12)] } @defproc[(primitive-root [n Integer]) (Union Natural #f)]{ Returns a primitive root of @math-style{Un} if one exists, otherwise @racket[#f] is returned. The modulus @racket[n] must be positive. @interaction[#:eval untyped-eval (primitive-root 5) (primitive-root 6)] } @defproc[(primitive-roots [n Integer]) (Listof Natural)]{ Returns a list of all primitive roots of @math-style{Un}. The modulus @racket[n] must be positive. @interaction[#:eval untyped-eval (primitive-roots 3) (primitive-roots 5) (primitive-roots 6)] } @(close-eval untyped-eval)