Task: Stirling numbers of the second kind

C: #include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct stirling_cache_tag {
    int max;
    int* values;
} stirling_cache;

int stirling_number2(stirling_cache* sc, int n, int k) {
    if (k == n)
        return 1;
    if (k == 0 || k > n || n > sc->max)
        return 0;
    return sc->values[n*(n-1)/2 + k - 1];
}

bool stirling_cache_create(stirling_cache* sc, int max) {
    int* values = calloc(max * (max + 1)/2, sizeof(int));
    if (values == NULL)
        return false;
    sc->max = max;
    sc->values = values;
    for (int n = 1; n <= max; ++n) {
        for (int k = 1; k < n; ++k) {
            int s1 = stirling_number2(sc, n - 1, k - 1);
            int s2 = stirling_number2(sc, n - 1, k);
            values[n*(n-1)/2 + k - 1] = s1 + s2 * k;
        }
    }
    return true;
}

void stirling_cache_destroy(stirling_cache* sc) {
    free(sc->values);
    sc->values = NULL;
}

void print_stirling_numbers(stirling_cache* sc, int max) {
    printf("Stirling numbers of the second kind:\nn/k");
    for (int k = 0; k <= max; ++k)
        printf(k == 0 ? "%2d" : "%8d", k);
    printf("\n");
    for (int n = 0; n <= max; ++n) {
        printf("%2d ", n);
        for (int k = 0; k <= n; ++k)
            printf(k == 0 ? "%2d" : "%8d", stirling_number2(sc, n, k));
        printf("\n");
    }
}

int main() {
    stirling_cache sc = { 0 };
    const int max = 12;
    if (!stirling_cache_create(&sc, max)) {
        fprintf(stderr, "Out of memory\n");
        return 1;
    }
    print_stirling_numbers(&sc, max);
    stirling_cache_destroy(&sc);
    return 0;
}








VB: Imports System.Numerics

Module Module1

    Class Sterling
        Private Shared ReadOnly COMPUTED As New Dictionary(Of String, BigInteger)

        Private Shared Function CacheKey(n As Integer, k As Integer) As String
            Return String.Format("{0}:{1}", n, k)
        End Function

        Private Shared Function Impl(n As Integer, k As Integer) As BigInteger
            If n = 0 AndAlso k = 0 Then
                Return 1
            End If
            If (n > 0 AndAlso k = 0) OrElse (n = 0 AndAlso k > 0) Then
                Return 0
            End If
            If n = k Then
                Return 1
            End If
            If k > n Then
                Return 0
            End If

            Return k * Sterling2(n - 1, k) + Sterling2(n - 1, k - 1)
        End Function

        Public Shared Function Sterling2(n As Integer, k As Integer) As BigInteger
            Dim key = CacheKey(n, k)
            If COMPUTED.ContainsKey(key) Then
                Return COMPUTED(key)
            End If

            Dim result = Impl(n, k)
            COMPUTED.Add(key, result)
            Return result
        End Function
    End Class

    Sub Main()
        Console.WriteLine("Stirling numbers of the second kind:")
        Dim max = 12
        Console.Write("n/k")
        For n = 0 To max
            Console.Write("{0,10}", n)
        Next
        Console.WriteLine()
        For n = 0 To max
            Console.Write("{0,3}", n)
            For k = 0 To n
                Console.Write("{0,10}", Sterling.Sterling2(n, k))
            Next
            Console.WriteLine()
        Next
        Console.WriteLine("The maximum value of S2(100, k) = ")
        Dim previous = BigInteger.Zero
        For k = 1 To 100
            Dim current = Sterling.Sterling2(100, k)
            If current > previous Then
                previous = current
            Else
                Console.WriteLine(previous)
                Console.WriteLine("({0} digits, k = {1})", previous.ToString().Length, k - 1)
                Exit For
            End If
        Next
    End Sub

End Module