sceiler
sceiler

Reputation: 1205

End of method reached but compiler jumps back in

just for fun I am trying to do the change making problem - more or less. My problem is that I get doubled results and through using the debugger I found out that the compiler jumps back into the method again even when it should finish.

private static void Main(string[] args)
{
string temp = Console.ReadLine();
int input;

if (int.TryParse(temp, out input))
{
    if(input == 0)
    {
        System.Environment.Exit(Environment.ExitCode);
    }
    else
    {
        ChangeMaking(input);
    }
}
else
{
    Console.WriteLine("Not a number.");
}
}

private static int ChangeMakingHelper(int input, int euro)
{
    return input / euro;
}

static int[] euro = { 1, 2, 5, 10, 20, 50, 100, 200, 500 };
static int counter = 0;
static List<int[]> result = new List<int[]>();
static int[] tempResult = new int[euro.Length];

private static void ChangeMaking(int input)
{
    for (int i = euro.Length -1; i >= 0; i--)
    {
        if(euro[i] <= input)
        {
            tempResult[i] = ChangeMakingHelper(input, euro[i]);
            input = input - euro[i];
            if((input % euro[i] != 0))
            {
                ChangeMaking(input % euro[i]);
            }
        }
    }
    result.Add(tempResult);
}

For example if the input is 11 then after the for-loop completes and adding tempResult to result the compiler jumps back into this part:

            if((input % euro[i] != 0))
            {
                ChangeMaking(input % euro[i]);
            }

My expected behavior for input 11 would be one array with this values {1, 0, 0, 1, 0, 0, 0, 0, 0} which I get but doubled.

Upvotes: 0

Views: 66

Answers (1)

AJ Richardson
AJ Richardson

Reputation: 6820

The issue is that you are using static variables to pass data between function calls. Don't do that. Use return values instead.

public static void Main()
{
    var result = ChangeMaking(11);
    Console.WriteLine(string.Join(", ", result));
}

private static int ChangeMakingHelper(int input, int euro)
{
    return input / euro;
}

static readonly int[] euro = { 1, 2, 5, 10, 20, 50, 100, 200, 500 };

private static int[] ChangeMaking(int input)
{
    var result = new int[euro.Length];
    for (int i = euro.Length -1; i >= 0; i--)
    {
        if (euro[i] <= input)
        {
            result[i] += ChangeMakingHelper(input, euro[i]);
            input = input - euro[i];
            if (input % euro[i] != 0)
            {
                var tempResult = ChangeMaking(input % euro[i]);
                // Transfer the results to the local result array
                for(int j = 0; j < result.Length; j++)
                    result[j] += tempResult[j];
            }
            // Also add a break statement here so you don't add the lower values twice!
            break;
        }
    }
    return result;
}

Fiddle: https://dotnetfiddle.net/7WnLWN

By the way, the reason you ended up with 2 arrays in your output is because you called ChangeMaking recursively, so it got called twice, so it called result.Add(tempResult) twice. Getting rid of the static variables as I have shown above fixes that.

Also, there's probably a more efficient way to do this without recursion, but that would require restructuring your algorithm a bit, so I'll leave that to you to figure out :)

Upvotes: 2

Related Questions