Since I've been learning Python in my spare time over the summer, and seeing how I'm an amateur mathematician and all, I decided the first thing worth coding was this historic algorithm of the greeks. Well, my first surprise was how small and readable the thing was. It uses some built-in functions from Python, but those are easily explained.
So, without further ado, the code:
def mod(a):
return lambda x: x % a != 0 or x == a;
def sieve(s, n):
s = filter(mod(s[n]), s)
if (s[n+1] > s[-1]**0.5): return s;
else: return sieve(s, n+1)
def start(x):
s = range(2, x)
print sieve(s, 0)
The first definition sets up a nice little functional; that is, a function that begets only further functions. This in particular generates a function that tests if a number is coprime with a, so that mod(2) accepts only two and subsequent odd numbers.
The second definition is the meat of the sieve. It runs by the graces of tail recursion. Each recursion filters out from the sieve all the numbers that are not coprime with the next number on the list. The recursion only runs as long as the factors are less the square root (the **0.5 part) of the largest number still in the list, since possible factors are never greater than the square root of a number. This speeds up the algorithm by a negligible amount — the first step (write down a list of primes) is always linear, so other optimisations are kind of moot.
Finally, the last definition seeds the thing with an arbitrarily sized list. Start the thing by calling, say, start(100) or some larger number, if the stack will handle it.
So elegant. So pretty. This almost makes me want to become a computer scientist. Almost, mind you. I'm not giving up my chosen profession yet.
I'm thinking the next trick will be to write a universal Turing machine. That'd be really swift.