The Limber Lambda

Eric Smith’s technical musings

“Sharpen Up” Series: Episode 6

leave a comment »

A colleague brought my attention to this brain-teaser, from Project Euler:

The series, 11 + 22 + 33 + 44 + … + 1010 = 10405071317.

Find the last ten digits of the series, 11 + 22 + 33 + 44 + … + 10001000

Having a Unix background, my first instinct was to fire up bc which I know can deal with integers of any size you like—such a calculator is known as an arbitrary precision calculator.

Here’s the one-liner, together with execution time:

image

Now, if you’re a Java programmer, you’ll know about java.math.BigInteger which is the implementation of an arbitrary precision integer.  Sadly, in the .NET world there is no built-in equivalent (soon to change in .NET 4.0).

What I did find interesting though was that the default (and only) implementation of integer in a lot of languages, including Python and Ruby is of the arbitrary precision variety (this also applies to Scheme and Lisp).  Since I have two implementations of python installed on my PC, namely cpython and IronPython, I could benchmark them from the command line.

First, cpython: image And … IronPython:

imageUnfortunately the initialisation of the python runtime puts a nasty skew on our comparison in the case of IronPython.

Somehow, that just feels like cheating though, and even though there aren’t any set rules on Project Euler about how you come to the answer, of course, you just feel like you should be doing it a clever way; read: no use of a big integer library, built-in or otherwise.

The solution is simple, but deceptively so—why would we need to keep track of all those “more significant digits” if we never need them?  As long as we keep our eight byte integer from overflowing, we should be fine.  Hence our BigInteger-free C# version:

class Program 
{
    static void Main(string[] args)
    { 
        var largest = 10L*10*10*10*10*10*10*10*10*10; 
        var tot = 0L; 
        for (int i = 1; i < 1001; i++)
        { 
            var exp = 1L; 
            for (int j = 0; j < i; j++)
                exp = (exp * i) % largest;
            tot = (tot + exp) % largest;
        }
        Console.WriteLine(tot);
    } 
}

And the result:

image

Advertisement

Written by Eric Smith

May 12, 2009 at 2:58 PM

Posted in Fun

Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.