Return amount of denominations

PPopulus9/10/2022
static void RunExerciseNineteen()
        {
            int price = 150;
            Console.WriteLine($"It'll cost you: {price}\nHow much are you providing?");
            int input = Convert.ToInt32(Console.ReadLine());
            int[] denominations = new int[] { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
            int temp = 0;

            int retur = input - price; // Remainder. (Negative if insufficient).
            Console.WriteLine(retur); // Print how much is owed.
            if (retur < 0)
            {
                Console.WriteLine("You didn't provide enough funds.");
            } else if (retur > 0)
            {
                for (int i = denominations.Length - 1; i >= 0; i--)
                {
                    if (denominations[i] / retur == 1 && retur > denominations[i])
                    {
                        retur += denominations[i];
                    }
                }
            }
            Console.WriteLine("Retur: " + retur);
        }


I'm having trouble constructing the logic behind returning bills. Am I on the right path? What am I missing?
PPobiega9/10/2022
Isnt the expected output something like... "you get 1x 500, 2x 20, 1x 2 in return"
PPobiega9/10/2022
retur += denominations[i]; seems very curious to me
PPobiega9/10/2022
retur, before being modified, holds how much change you need to give back, as an int
PPopulus9/10/2022
You're right, that's what the output is supposed to look like.
PPopulus9/10/2022
I admit I am very confused. Should I create another array to hold the bills? Am I silly for thinking it can be done with 1 single 'retur' variable?
PPopulus9/10/2022
I find myself removing and starting over and writing the same thing as before.
PPobiega9/10/2022
it can't be done with a single int, no
PPobiega9/10/2022
imagine it like so: the expected return for 752 should total 752
PPobiega9/10/2022
but its not 752 itself
PPobiega9/10/2022
its 1x 500, 1x 200, 1x 50, 1x 2
PPobiega9/10/2022
My first instinct is to have your calculate method return a Dictionary<int,int>
PPobiega9/10/2022
where the key is your denomination, and your value the count
PPopulus9/10/2022
I will look into it. My beginner instinct is to create variables for each of the denominations but that feels so.. unsatisfactory.
PPobiega9/10/2022
yeah don't do that
PPobiega9/10/2022
the alternative to a dict would be an int[], where each position of the array matches the position of the denomination
PPopulus9/10/2022
That I can wrap my head around.
PPopulus9/10/2022
static void RunExerciseNineteen()
        {
            int price = 150;
            Console.WriteLine($"It'll cost you: {price}\nHow much are you providing?");
            int input = Convert.ToInt32(Console.ReadLine());
            int[] denominations = new int[] { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
            int[] bills = new int[denominations.Length];

            int retur = input - price; // Remainder. (Negative if insufficient).
            Console.WriteLine("retur " + retur); // Print how much is owed.
            if (retur < 0)
            {
                Console.WriteLine("You didn't provide enough funds.");
            } else if (retur > 0)
            {
                for (int i = denominations.Length - 1; i >= 0; i--)
                {
                    while (retur % denominations[i] > 0)
                    {
                        bills[i]++;
                    } 
                }
            }
            Console.WriteLine("Retur: " + retur);
        }
PPopulus9/10/2022
I fear it's too simple.
PPobiega9/10/2022
do you know about unit tests?
PPobiega9/10/2022
if you wrote this as a pure function instead of as a void, you could slap together a test suite that would let you verify that things work as expected
PPopulus9/10/2022
I do not know of unit tests.
PPobiega9/10/2022
Would you like to learn?
PPopulus9/10/2022
Sure
PPobiega9/10/2022
I can jump on a voice call for a while if you have the time
PPopulus9/10/2022
Yeah, join a channel and I'll pop in
PPobiega9/10/2022
#dev-vc-0
PPobiega9/10/2022
public static Dictionary<int, int> AsChange(this int amount)
{
    if (amount < 0)
        throw new ArgumentException("Can't calculate negative change.", nameof(amount));

    var dict = new Dictionary<int, int>();

    foreach (var denomination in _denominations)
    {
        if (amount < denomination)
            continue;

        var count = amount / denomination;
        dict.Add(denomination, count);
        amount -= count * denomination;
    }

    return dict;
}
PPopulus9/10/2022
public static Dictionary<int, int> AsChange(int amount)
        { // Thanks to "Pobiega" from the C# Discord.
            int[] _denominations = new int[] { 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1 };

            if (amount < 0)
                throw new ArgumentException("Can't calculate negative change.", nameof(amount));

            var dict = new Dictionary<int, int>();

            foreach (var denomination in _denominations)
            {
                if (amount < denomination)
                    continue;

                var count = amount / denomination;
                dict.Add(denomination, count);
                amount -= count * denomination;
            }

            return dict;
        }

        static void RunExerciseNineteen()
        { // Thanks to "Pobiega" from the C# Discord.
            int price = 150;
            Console.WriteLine($"It'll cost you: {price}\nHow much are you providing?");
            int input = Convert.ToInt32(Console.ReadLine());
            int[] denominations = new int[] { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };

            int retur = input - price; // Remainder. (Negative if insufficient).
            Console.WriteLine("retur " + retur); // Print how much is owed.

            var temp = AsChange(retur);
            foreach (var i in temp)
            {
                Console.WriteLine(i);
            }
        }


Thanks for your help. I did it like this. Now I just need to learn how to deal with Dictionaries to create pretty print statements for the bills. (=
PPobiega9/10/2022
when looping over a dictionary with foreach, you get access to both key and value
PPobiega9/10/2022
foreach (var kvp in change)
{
    Console.WriteLine($"{kvp.Value}x {kvp.Key}");
}
PPobiega9/10/2022
🙂
PPopulus9/10/2022
Wonderful. You're an asset to this community.