Răzvan Flavius Panda
Răzvan Flavius Panda

Reputation: 22116

How to partially initialize an array?

I am working on optimizing for speed a method to calculate a triangle number for ProjectEuler - Problem 12.

I need to somehow be able to initialize the first element in an array:

private static ulong[] numbersArray = new ulong[5000];

One way to calculate a triangle number would be:

public static ulong GetTriangleFormula(ulong n)
{
    return n * (n + 1) / 2;
}

But it has a computational complexity somewhere between O(n) and O(n^2) so I was thinking I could trade memory for run speed by computing the numbers recursively and storing the results in a Dictionary/array. Since the triangle numbers will be calculated successively in the final solution it should work.

Computing the n-th triangle number should become a simple sum of numbersArray[n - 2] and n.

Using a Dictionary the computation was much slower for successive triangle number computation from 1 to 1000:

private static Dictionary<ulong, ulong> numbers = new Dictionary<ulong, ulong>() { { 1, 1 } };
public static ulong GetTriangleDictionaryRecursive(ulong n)
{
    if (!numbers.ContainsKey(n))
        numbers[n] = n + GetTriangleDictionaryRecursive(n - 1);
    return numbers[n];
}

I added {1, 1} to the Dictionary so that i wouldn't have to always check at the beginning of the GetTriangleDictionaryRecursive method for the base case:

if(n == 1) return 1;

But the results were that it was about 40 times slower than the formula method.

So now i am trying to write a method using an array of type ulong[] but I do not know how I can initialize only the first element with value 1 (the others being default for ulong 0).

public static ulong GetTriangleArrayRecursive(ulong n)
{
    if (numbersArray[n - 1] == 0)
        numbersArray[n - 1] = n + GetTriangleArrayRecursive(n - 1);
    return numbersArray[n - 1];
}

Thanks for your help! :)

Upvotes: 0

Views: 1563

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1503290

I have no idea whether or not it's appropriate for the Euler problem, but in general if I want to do more work than a single simple expression for initialization, I do it like this:

private static readonly ulong[] numbersArray = CreateNumbersArray();

private static ulong[] CreateNumbersArray()
{
    ulong[] ret = new ulong[5000];
    ret[0] = 1;
    return ret;
}

Or you can do it in a static constructor:

private static readonly ulong[] numbersArray;

static FooClass()
{
    numbersArray = new ulong[5000];
    numbersArray[0] = 1;
}

Are you really sure it's appropriate to make this a static variable, by the way?

Upvotes: 1

Related Questions