Genießen Sie diesen Titel jetzt und Millionen mehr, in einer kostenlosen Testversion

Kostenlos für 30 Tage, dann für $9.99/Monat. Jederzeit kündbar.

A Short Course in Discrete Mathematics

A Short Course in Discrete Mathematics

Vorschau lesen

A Short Course in Discrete Mathematics

480 Seiten
10 Stunden
Aug 28, 2012


What sort of mathematics do I need for computer science? In response to this frequently asked question, a pair of professors at the University of California at San Diego created this text. Its sources are two of the university's most basic courses: Discrete Mathematics, and Mathematics for Algorithm and System Analysis. Intended for use by sophomores in the first of a two-quarter sequence, the text assumes some familiarity with calculus. Topics include Boolean functions and computer arithmetic; logic; number theory and cryptography; sets and functions; equivalence and order; and induction, sequences, and series. Multiple choice questions for review appear throughout the text. Original 2005 edition. Notation Index. Subject Index.
Aug 28, 2012

Über den Autor

Ähnlich wie A Short Course in Discrete Mathematics

Ähnliche Bücher

Ähnliche Artikel


A Short Course in Discrete Mathematics - Edward A. Bender

A Short Course in Discrete Mathematics

Edward A. Bender

S. Gill Williamson


Copyright © 2005 by Edward A. Bender and S. Gill Williamson All rights reserved.

Bibliographical Note

A Short Course in Discrete Mathematics is a new work, first published in book form by Dover Publications, Inc., in 2005.

Library of Congress Cataloging-in-Publication Data

Bender, Edward A., 1942 –

A short course in discrete mathematics / Edward A. Bender, S. Gill Williamson.

p. cm.

Includes indexes.


1. Mathematics. 2. Computer science — Mathematics. I. Williamson, S. Gill (Stanley Gill) II. Title.

QA39.3.B453 2005

510 — dc22


Manufactured in the United States by Courier Corporation



Discrete mathematics is an essential tool in almost all subareas of computer science. Interesting and challenging problems in discrete mathematics arise in programming languages, computer architecture, networking, distributed systems, database systems, AI, theoretical computer science, and other areas.

The course. The University of California, San Diego, has a lower-division two-quarter course sequence in discrete mathematics that includes Boolean arithmetic, combinatorics, elementary logic, induction, graph theory and finite probability. These courses are core undergraduate requirements for majors in Computer Science, Computer Engineering, and Mathematics-Computer Science. This text, A Short Course in Discrete Mathematics, was developed for the first quarter and Mathematics for Algorithm and System Analysis was developed for the second quarter.

This book consists of six units of study (Boolean Functions and Computer Arithmetic; Logic; Number Theory and Cryptography; Sets and Functions; Equivalence and Order; and Induction, Sequences and Series), each divided into two sections. Each section contains a representative selection of problems. These vary from basic to more difficult, including proofs for study by mathematics students or honors students.

The review questions. Multiple Choice Questions for Review appear at the end of each unit. The explanatory material in this book is directed towards giving students the mathematical language and sophistication to recognize and articulate the ideas behind these questions and to answer questions that are similar in concept and difficulty. Many variations of these questions have been successfully worked on exams by most beginning students using this book at UCSD.

Students who master the ideas and mathematical language needed to understand these review questions gain the ability to formulate, in the neutral language of mathematics, problems that arise in various applications of computer science. This skill greatly facilitates their ability to discuss problems in discrete mathematics with other computer scientists and with mathematicians.

Table of Contents

Title Page

Copyright Page


Unit BF - Boolean Functions and Computer Arithmetic

Unit Lo - Logic

Unit NT - Number Theory and Cryptography

Unit SF - Sets and Functions

Unit EO - Equivalence and Order

Unit IS - Induction, Sequences and Series

Solutions for Boolean Functions and Computer Arithmetic

Solutions for Logic

Solutions for Number Theory and Cryptography

Solutions for Sets and Functions

Solutions for Equivalence and Order

Solutions for Induction, Sequences and Series

Notation Index - (Page references herein refer to book’s chapter numbering system.)

Subject Index



Unit BF

Boolean Functions and Computer Arithmetic

Section 1: Boolean Functions

We recall the concept of a function and some of the terminology.

Definition 1 (Function) If A and B are sets, a function from A to B is a rule that tells us how to find a unique b B for each a A. We write f(a) = b and say that f maps a to b. We also say the value of f at a is b.

We write f : A → B to indicate that f is a function from A to B. We call the set A the domain of f and the set B the range or, equivalently, codomain of f.

To specify a function completely you must give its domain, range and rule.

In this section, we’ll study a special class of functions called boolean functions. General properties of functions are studied in Unit SF.

A Boolean function is a function f from the Cartesian product xn{0,1} to {0,1}. Alternatively, we write f : xn{0,1} → {0,1}. The set xn{0,1}, by definition, the set of all n-tuples (x1,···,xn) where each xi is either 0 or 1, is called the domain of f. The set {0,1} is called the codomain (or, sometimes, range) of f. The Cartesian product xn{0,1} is also written {0,1}n. This corresponds to writing the product of n copies of y as yn.

Example 1 (Tabular representation of Boolean functions) One way to represent a function whose domain is finite is with a table. Each element x of the domain has a row of the table listing the domain element x and the corresponding function value f(x). For example, the two tables

define Boolean functions f : x²{0,1} → {0,1} and g : x³{0,1} → {0,1}. In the case of f, the first two values of each row represent the argument of f and the third entry in the same row represents the value of f at that argument. We have f(0,0) = 0, f(0,1) = 1, f(1,0) = 0, and f(1,1) = 1. For g, the first three values of each row represent an element of x³{0,1} (a triple (p,q,r) of 0’s or 1’s) and the fourth entry of the row represents the value of g(p, q, r). Thus, g(0, 0, 0) =1, g(0, 0, 1) = 1, g(0, 1, 0) = 0, etc.

Notice that we have used p, q and r for variables instead of x, y and z, which are usually the choice for variable names in algebra. We can choose any names we please for variables. Names such as p, q and r are commonly used in the study of Boolean functions.

The tabular form of a Boolean function is often called a truth table because of the connection between Boolean functions and logic, which we will study later.

Example 2 (The number of Boolean functions) How many Boolean functions are there with domain x³{0,1}? More generally, how many Boolean functions are there with domain xn{0,1}? We do this in two steps.

First, how many elements are there in the domain xn{0,1}? We use the notation |S| to denote the number of elements of S (also called the cardinality of S). Thus we are asking for the value of |xn{0,1}|. We can select an element of the domain by making n choices x1,x2,...,xn where xi ∈ {0,1} for i = 1,2,...,n. Thus there are two choices for x1 and two choices for x2 and so on. The total number of elements in the domain is thus 2 × 2 × ··· × 2 = 2n. In other notation, |xn{0,1}| = |{0,1}|n. If you have trouble seeing why this is true, the footnote may help.¹

Second, we must construct the Boolean function. In constructing a Boolean function h : x³{0,1} → {0,1}, there are two possible choices that we could assign to h(p, q, r) for each (p,q,r) ∈ x³{0,1}. We saw in the previous paragraph that there are 2³ elements (p, q, r) in x³{0,1}. Thus the total number of Boolean functions h . In general, the number of Boolean functions h : xn.

In this section we are concerned about a particular way of representing Boolean functions in terms of certain more primitive representations. An example that is familiar from high school mathematics is the representation of polynomial and rational functions, such as 1+x, 1+x², (2+x²−x³)/(1+x²), starting with the constant functions c and the identity function x. All of these functions are created by adding, multiplying, subtracting, and/or dividing the simple starting functions.

Example 3 (The simplest Boolean functions: constants, identity, not) The simplest functions are the constant functions. Since we have only two constants, 0 and 1, there are two constant Boolean functions.

= 2² = 4 one-variable Boolean functions and since there are two constants, there are 4 −2 = 2 nonconstant, one-variable Boolean functions. One is the identity function f(p) = p for all p ∈ {0,1}. The other one-variable function is "not p." For the moment, let’s call this function n(p). The definition is simple: n(p) = 0 if p = 1, n(p) = 1 if p = 0. This function is usually denoted by ∼p rather than n(p). Thus, we would write ∼0 = 1 and ∼1 = 0. The symbol is called the unary operator not. Unary means it is a function that has one variable. The minus sign in ordinary arithmetic is a familiar example of a unary operator.

Example 4 (Two-variable Boolean functions: and, or, exculsive or) = 2⁴ = 16 two-variable Boolean functions f (p, q). From the previous example, 2 of these are constant, 2 of them are not constant and depend only on p, and 2 of them are not constant and depend only on q. This leaves 16 − 6 = 10 functions that depend on both variables. We certainly don’t want to give names to all of them! In this example, we define three commonly-used, two-variable Boolean functions.

The first function we define is "p and q." Again, for the moment, let’s call this function (a function of two Boolean variables) a(p, q). By definition, a(p, q) = 0 unless both p = 1 and q = 1, in which case a(p, q) = 1. The function a(p, q) is denoted by p Λ q. We write 0 Λ 0 = 0, 0 Λ 1 = 0, 1 Λ 0 = 0, and 1 Λ 1 = 1.

The next function is "p or q." Again, for the moment, let call this function (a function of two Boolean variables) o(p,q). By definition, o(p,q) = 1 unless both p = 0 and q = 0, in which case o(p, q) = 0. The function o(p, q) is denoted by p V q. We write 0 V 0 = 0, 0 V 1 = 1, 1 V 0 = 1, and 1 V 1 = 1.

The last function is the exclusive or function. It is written xor(p, q) or p q. By definition p q = 0 if p = q and p q = 1 if p q.

Here are our functions in tabular form:

The symbols V, Λ, and ⊕ are called binary operators because they involve two variables (like addition and multiplication in ordinary arithmetic).

Example 5 (Boolean functions and logic) People often call Boolean variables such as p and q statement variables. Why? Because Boolean functions are related to logic. In logic we think of p and q as statements, 0 as false, and 1 as true.

Suppose p stands for I have classes tomorrow and q stands for I will stay home tomorrow. Let’s look at our basic Boolean functions.

p stands for "not (I have classes tomorrow), which can be written in more normal English as I do not have classes tomorrow. As mentioned earlier, 0 is thought of as false and 1 is thought of as true." According to our definition of the function ∼, if p is true, then ∼p is false. This is also true about our statements: If the statement I have classes tomorrow is true, then the statement I do not have classes tomorrow is false.

pΛq stands for the statement, I have classes tomorrow and I will stay home tomorrow. You should verify that the definition of p Λ q agrees with our usual interpretation of and: p Λ q is true if and only if both p and q are true. The statement p Λ q is also read "p but q", especially if q is surprising as in I have classes tomorrow, but I will stay home tomorrow.

p V q stands for the statement, Either I have classes tomorrow or I will stay home tomorrow. Unfortunately or is ambiguous in English. If I have classes and also stay home, some people may think the statement is not true. Others may think that it is true. Our definition of or is not ambiguous: p V q is true if either p or q or both are true.

p q stands for the statement Either I have classes tomorrow or I will stay home tomorrow, but not both. Why is this? The value of p q is 1 (true) if and only if one of p and q is 1 (true) and the other is 0 (false).

When converting ordinary language into symbolic form, it is important to be aware of ambiguities so that the statements can be converted correctly. What we have been discussing is called propositional logic. We will explore the connection between Boolean functions and logic in the unit on logic.

Because of the close connection with logic, the tabular form of a Boolean function is often called a truth table.

Why are the Boolean functions represented by ∼, Λ, V and ⊕ important? In the previous example, we have seen a hint of their importance in logic. They are also important because they can be used to define more complex Boolean functions, in the same way that the basic operations of arithmetic can be used to define more complex algebraic functions.

Example 6 (Defining more complex Boolean functions) We could try to define a Boolean function using ∼, Λ, and V by stating that


The problem with this definition is that it is not clear what the order of application of these operators should be. It is conventional to give top priority to the ∼ operator. Thus the expression used to define f can be clarified a bit: f(p,q) = p Λ (∼q) V (∼p) Λ q. In addition, the order in which the Λ and V are performed must be specified by grouping them in the definition of the function f. Thus, as an example, we could group them

(not ambiguous)

Now the function f is clearly defined. You should make sure that you use enough parentheses. Using too few may result in an ambiguous function definition. Using more than needed does not change a function. For example, the usage of ∼ is defined by the precedence rules, so we could just write

(still not ambiguous)

If you’re unsure about precedence rules, be safe and use extra parentheses!

Using the formula for f we can compute values and give f in tabular form:

This is the exclusive or function. We have proved p q = (p Λ ∼q) V (∼p Λ q).

In the previous example, we found that pq could be written as an equivalent Boolean function using ∼, Λ and V. This is a particular example of a much more general result:

Theorem 1 (Representing functions) Suppose n > 0 and f : xn{0,1} → {0,1}. There is a function g using only ∼, V and Λ that is equal to f. In fact, we can use just and Λ or, if we prefer, we can use just and V.

Proof: We’ll illustrate how to do this with the function

Look at the rows in the table where the f = 1. The first such is (p, q, r) = (0,0,1). Note that (∼p) Λ ((∼q) Λ r) equals 1 when (p, q, r) = (0,0,1) and equals 0 otherwise.² Similarly, for the rows (p, q, r) = (0,1,0) and (p, q, r) = (1,1,1), we have (∼p) Λ (q Λ (∼r)) and p Λ (q Λ r). You should be able to see why the function

g (p, q, r) = ((∼p) Λ ((∼q) Λ r)) V ((∼p) Λ (q Λ (∼r))) V (p Λ (q Λ r))

is equal to f.

It should be clear how to do this in general: Construct an appropriate anding for each row of the table where the function equals 1. Then or all these andings together. This proves the first claim.

In this paragraph we take a break to discuss some terminology. An expression of this sort, namely an or of ands of variables and their negations, is called disjunctive normal form. Where did disjunctive come from? An or is sometimes called a disjunction. If we replace the roles of and and or, we obtain conjunctive normal form, so called because and is called a conjunction. End of terminology discussion and back to the proof.

One might object that we haven’t taken care of the case when the function is a contradiction since then there are no rows where the function is 1. This is taken care of by 0 or, if you prefer, by p Λ ∼p.

How can we get rid of V? We claim that

P V Q V R V···VT and ∼((∼P) Λ (∼Q) Λ (∼R) Λ···Λ (∼T))

are equal. Why? The only way the first expression can be 0 is for all of P,Q,...,T to be 0. The only way the second expression can be 0 is for the expression inside the large parentheses to be 1. The only way this can happen is for all of ∼P, ∼Q,..., ∼T to be 1 — which is the same as all of P, Q,..., T being 0. Applying this to g with

P = (∼p) Λ ((∼q) Λ r), Q = (∼p) Λ (q Λ (∼r)), R = p Λ (q Λ r),

and none of the terms..., T, we have the equivalent function

∼(∼((∼p) Λ ((∼q) Λ r)) Λ ∼((∼p) Λ (q Λ (∼r))) Λ ∼(p Λ (q Λ r))).

You should see that this works in general.

What about getting rid of Λ instead of V? A similar trick can be used, working from the inside of the formula instead of from the outside. We leave it to your inventiveness to find the trick.

In the last half of the previous proof, we used a trick that let us replace V with Λ. In fact, this trick is used often enough that we should call it a rule.³ It is very useful to have a catalog of simple rules to help in deciding whether or not functions are equal, without having to always construct tables of functions. Here is such a catalog. In each case the standard name of the rule is given first, followed by the rules as applied first to Λ and then to V.

Theorem 2 (Algebraic rules for Boolean functions) Each rule states that two different-looking Boolean functions are equal. That is,they look different but have the same table.

These rules are algebraic rules for working with Λ, V, and ∼. You should memorize them as you use them. They are used just like rules in ordinary algebra: whenever you see an expression on one side of the equal sign, you can replace it by the expression on the other side. Each of the rules can be proved by constructing tables for the functions on each side of the equal sign and verifying that those tables give the same function values.

Truth tables are similar to the tabular method for proving set identities (see Section 1 of Unit SF). The algebraic rules for Boolean functions are almost identical to the rules for sets in Section 1 of Unit SF. When two apparently very different situations (sets and Boolean functions in this case) are similar, one should look for an explanation. We provide an explanation in Unit Lo.

One useful consequence of this connection is that we can use Venn diagrams to prove identities for Boolean functions. (If you are not familiar with Venn diagrams, read the first four pages of Unit SF.) How does this work? Think of the variables p, q and so on as sets. Then make the translations:

Λ to ∩, V to ∪, ∼ to complement.

The universal set is 1 and the empty set is 0. For example, you can prove the first of DeMorgan’s Rules for Boolean functions, by showing that (P Q)c and Pc ∪ Qc give the same regions in the Venn diagram for two sets P and Q. Try it.

Example 7 (Manipulating functions) We want to simplify the function

(∼(p Λ ∼q)) Λ (p V q).

Here are our calculations:

Except for the last step, we gave each step in detail. In actual calculations, you can combine steps as we did in the last step. How you decide to manipulate things can make a big difference. For example,

The same thing happens in algebra; however, you are more likely to do things the shorter way in algebra because you are more familiar with those manipulations. There is a trade off between taking time to try finding a shorter way and simply going ahead. This is a problem faced by designers of symbolic manipulation packages such as Maple@ and Mathematica®.

Exercises for Section 1

1.1. Let f = she is out of work and s = she is spending more. Write the following statements in symbolic form:

She is out of work but she is spending more.

Neither is she out of work nor is she spending more.

1.2. Let r = she registered to vote and υ = she voted. Write the following statements in symbolic form: She registered to vote but she did not vote.

1.3. Make a truth table for ∼((p Λ q) V ∼(p V q)).

1.4. Make a truth table for ∼p Λ (q V ∼r).

1.5. Make a truth table for (p V (∼p V q)) Λ ∼(q Λ ∼r).

1.6. Using DeMorgan’s rule, state the negation of the statement: Mary is a musician and she plays chess.

1.7. Using DeMorgan’s rule, state the negation of the statement: The car is out of gas or the fuel line is plugged.

1.8. Show that p V (p Λ q) = p follows from the idempotent rule, distributive rule, and the absorption rule p Λ (p V q) = p.

1.9. Is the function (p Λ q) V r equal to the function p Λ (q V r)?

1.10. Is the function (p V q) V (p Λ r) equal to the function (p V q) Λ r?

1.11. Is the function ((∼p V q) Λ (p V ∼r)) Λ (∼p V ∼q) equal to the function ∼(p V r)?

1.12. Is the function (r V p) Λ (∼r V (p Λ q)) Λ (r V q) equal to the function p Λ q?

1.13. Is the function ∼(p V ∼q) V (∼p Λ ∼q) equal to the function ∼p?

1.14. Is the function ∼((∼p Λ q) V (∼p Λ ∼q)) V (p Λ q) equal to the function ∼p?

1.15. Is the function (p Λ (∼(∼p V q))) V (p Λ q) equal to the function p V q?

Section 2: Number Systems and Computer Arithmetic

The number system we are most familiar with is the base 10system. In that system, an n-digit number is represented by a sequence of digits, dn-1 ··· d1 d0. For example, 243598102 is a 9-digit number base 10. The numerical value of the number dn−1 ··· d1 d0 is dn – 110n – ¹+dn−210n−2+...+d110¹+d010⁰. We are familiar, from elementary school, with various tedious algorithms (treated with mystical reverence by the back-to-basics educational advocates) for adding, subtracting, multiplying, and dividing numbers in the base 10 system using pencil and paper calculations. Although these algorithms are sometimes useful, mostly we use our hand calculators or computers to do these calculations. Here, for example, is the almost instantaneous result of asking a computer program to compute 500!, the product of the first 500 positive integers, and represent the answer in base 10.

Example 8 (Base 256) There is no reason why we have to use base 10. For certain applications, base 256 is used. In base 10 we have ten familiar symbols to use for the digits, namely


What do we use in base 256 for the symbols used for the digits of numbers? One obvious choice is to use

[0], [1], ... , [254], [255] .

We have written these digit symbols with square braces to avoid confusion when digit symbols are concatenated to form numbers. In the base-256 system, an n-digit number, as in base 10, is represented by a sequence dn−1... d1 d0 where each di is a digit symbol (from [0], [1],...,[254], [255]). For example, [12][43][251][198][210][122][2][0][0][0] is a 10-digit number base 256. The numerical value of the number dn−1 ... d1d0 is dn−1256n−1 +dn−2256n−2+... +d1256¹+d0256⁰. The symbols di are used in two different ways here, but in practice there should be no confusion. For example, the 10-digit base-256 number [12][43][251][198][210][122][2][0][0][0] has numerical value

12 . 256⁹ + 43 • 2568 + 251. 256⁷ + 198 . 256⁶ + 210 . 256⁵ + 122 . 256⁴ + 2 • 256³.

In base 10, this number is 57479750209175623303168.

Example 9 (Number systems base b) In fact, a number system can be defined for any integer base b > 1. We need unique symbols for the digit symbols, say [0], [1],..., [b − 1] or, more generally, D0, ... , Db−1. The digit symbol Di is said to have index or rank i in the list of digit symbols for the base-b number system. If d is a digit symbol, we use ι(d) (iota of d) to represent its rank in the list of digit symbols. Thus, ι() = κ or ι([κ]) = κ in the lists of digit symbols just described. Then, an n-digit positive number can be represented uniquely as dn−1 ... d1 d0 where each di is one of the digit symbols D0,...,Db−1 and ι(dn−1) > 0. The numerical value of this number is ι(dn−1)bn−¹+ι(dn−2)bn−²+...+ι(d1)b¹+ι(d0)b⁰. In base b, using digit symbols [0],[1],...,[b − 1], the nonnegative numbers, ordered according to numerical value, start off [0], [1], [2],..., [b − 1]. These are the 1-digit numbers, base b. Next come the 2-digit numbers

[1][0],..., [1][b − 1], [2][0],..., [2][b − 1],..., [b − 1][0]...,[b −1][b − 1].

If you wanted to do paper and pencil calculations for addition, subtraction, multiplication or long division in base b, you could use the back-to-basics algorithms with base-b digit symbols instead of base-10 symbols. We will study such algorithms for b = 2 later in this section.

The largest n-digit number in base b is

If we add [1] to it, we get

[b − 1][b − 1] ... [b − 1] + [1] = [1][0] ... [0],

which is the smallest (n + 1)-digit number and has value bn.

Example 10 (Transforming numbers between bases) Given a number, how can we write it in base b?

It would be nice to begin with an example in base 10, but there’s no familiar way to specify a number without using base 10. We can fake it a bit by writing the number in words. Let’s write twenty-one hundred seven in base 10.

If we divide by 10, we obtain two hundred ten and a remainder of seven. Thus our rightmost digit is [7]. Now start again with two hundred ten.

If we divide by 10, we obtain twenty-one and a remainder of zero. Thus our rightmost digit is [0]. Now start again with twenty-one.

If we divide by 10, we obtain two and a remainder of one. Thus our rightmost digit is [1]. Now start again with two.

If we divide by 10, we obtain zero and a remainder of two. Thus our rightmost digit is [2]. Since we’ve reached zero, we’re done.

Putting the rightmost digits together in order, we have [2][1][0][7], or 2107 in the usual notation for base-10 numbers.

Now suppose our number N is written in the familiar way (base 10) and we want to write it in base b. We proceed in the same manner as in the previous paragraph, dividing by b each time instead of by 10.

Here is an example for base 256, using digit symbols [0], [1], . . . , [255]. Suppose we are given the decimal (base-10) number 3865988647 and want to write it in base 256.

38659886477/256 is 15101518 with a remainder of 39. Thus our rightmost digit is [39]. Now start again with 15101518.

15101518/256 is 58990 with a remainder of 78. Thus our rightmost digit is [78]. Now start again with 58990.

58990/256 is 230 with a remainder of 110. Thus our rightmost digit is [110]. Now start again with 230.

230/256 is 0 with a remainder of 230. Thus our rightmost digit is [230]. Since we’ve reached 0, we’re done.

Thus the base-10 number 3865988647 equals [230] [110] [78] [39] in base 256. We can check that this is correct:

[230][110][78][39] = 230 · 256³ + 110 · 256² + 78 · 256 + 39 = 38659886477.

Computer Arithmetic

In the remainder of this section, we will study base 2, 8, and 16 numbers. Instead of bases 2, 8 and 16, people also say

binary for base 2, octal for base 8 and hexadecimal for base 16.

You should practice converting some base-10 numbers of your choosing into their binary, octal and hexadecimal equivalents.

Computers, for the most part, work directly with base b = 2. The symbols for the digits are usually taken to be 0,1. Thus, 10011 = 2⁴ + 2¹ + 2⁰. In base ten, 10011 is denoted by 19. If the base needs to be mentioned explicitly in the mathematics, one usually writes it as a subscript: 100112 = 1910. Base 2 is inconvenient for people because it leads to long strings

Sie haben das Ende dieser Vorschau erreicht. Registrieren Sie sich, um mehr zu lesen!
Seite 1 von 1


Was die anderen über A Short Course in Discrete Mathematics denken

0 Bewertungen / 0 Rezensionen
Wie hat es Ihnen gefallen?
Bewertung: 0 von 5 Sternen