Discrete mathematics and combinatorial algorithms have already become a well-established part of most undergraduate mathematics and computer science curricula. However, many mathematicians still view algorithms as second-class citizens and computer scientists tend to do likewise with mathematical theorems. This book tries to bridge the gap between the two disciplines and leads the reader through an interesting amalgam of both, frequently switching between using mathematics to analyze algorithms and employing algorithms to prove theorems constructively. In addition to the standard topics like relations, graphs and counting methods, the book also includes more advanced chapters involving the solving of difference equations, discrete probability and applications to practical problems, e.g. mathematical biology. The exposition is self-contained, complemented by diverse exercises and also accompanied by an introduction to mathematical reasoning, culminating in a separate chapter on the basics of logic. The book is an excellent textbook for a one-semester undergraduate course and it includes a lot of additional material to choose from.