In this lecture, we did the Deutsch-Jozsa algorithm and Simon's algorithm. Let's start with the Deutsch-Jozsa algorithm. It doesn't look very impressive, as it solves a problem deterministically that can be solved classically with a probabilistic algorithm. However, Simon's algorithm, which was the immediate precursor to the factoring algorithm, looks quite similar to the Deutsch-Jozsa algorithm, so it appears that Deutsch-Jozsa was a critical step in the development of quantum algorithms.

Suppose we have a function f which maps the numbers 0 through 2^{n}−1 into {0,1}.
We will assume this is a *black-box* function; that is, you are not allowed to look at
any code which implements it (and in fact, we do not assume that such code necessarily exists).
We will call this function *constant* if it always takes the same value, and *balanced*
if there are an equal number of x's for which f(x)=0 and f(x)=1.
The Deutsch-Jozsa algorithm solves the problem of: given a function which is either constant or
balanced, which one is it. Classically, this problem requires 2^{n-1}+1 queries in the
worst case, as you could happen to be very unlucky, and check all x's which get mapped onto 0
before finding one x so f(x)=1. However, if you check the value of random x's, then after k queries,
the chance that you have not found both a 0 and a 1 in a black-box function is at least
1/2^{k-1}, as after the first query (which we may as well assume is a 0), the chance that
we will discover a 1 with each subsequent query is greater than 1/2.