How to generate Permutations with repetition recursively in C#

// 1: [6, 1, 1, 1, 1, 1, 1, 1, 1]
// 2: [1, 6, 1, 1, 1, 1, 1, 1, 1]
// 3: [1, 1, 6, 1, 1, 1, 1, 1, 1]
// 4: [1, 1, 1, 6, 1, 1, 1, 1, 1]
// 5: [1, 1, 1, 1, 6, 1, 1, 1, 1]
// 6: [1, 1, 1, 1, 1, 6, 1, 1, 1]
// 7: [1, 1, 1, 1, 1, 1, 6, 1, 1]
// 8: [1, 1, 1, 1, 1, 1, 1, 6, 1]
// 9: [1, 1, 1, 1, 1, 1, 1, 1, 6]

using System;

public static class PermutationsWithRep
{
    private static int numberOfCombos;

    public static void Main()
    {
        var collection = new[] { 6, 1, 1, 1, 1, 1, 1, 1, 1 };
        PermuteRep(collection);
    }

    private static void PermuteRep<T>(T[] workArray, int? end = null, int start = 0)
        where T : IComparable<T>
    {
        if (end == null)
        {
            end = workArray.Length - 1;
        }

        PrintPerm(workArray);

        for (int left = end.Value - 1; left >= start; left--)
        {
            for (int right = left + 1; right <= end; right++)
                if (workArray[left].CompareTo(workArray[right]) != 0)
                {
                    Swap(ref workArray[left], ref workArray[right]);
                    PermuteRep(workArray, end, left + 1);
                }

            var firstElement = workArray[left];

            for (int i = left; i <= end.Value - 1; i++)
            {
                workArray[i] = workArray[i + 1];
            }

            workArray[end.Value] = firstElement;
        }
    }

    private static void Swap<T>(ref T a, ref T b)
    {
        var temp = a;
        a = b;
        b = temp;
    }

    private static void PrintPerm<T>(T[] arr)
    {
        Console.WriteLine($"{++numberOfCombos}: [{string.Join(", ", arr)}]");
    }
}

How to generate Variations with repetition recursively in C#

// 1: [0, 0]
// 2: [0, 1]
// 3: [0, 2]
// 4: [1, 0]
// 5: [1, 1]
// 6: [1, 2]
// 7: [2, 0]
// 8: [2, 1]
// 9: [2, 2]

using System;

public static class VariationsWithRep
{
    private static int numberOfCombos;
    private static int n;
    private static int k;
    private static int[] workArr;

    public static void Main()
    {
        n = 3;
        k = 2;
        workArr = new int[k];

        GenerateVariationsWithRep();
    }

    private static void GenerateVariationsWithRep(int index = 0)
    {
        if (index >= k)
        {
            PrintCombo();
            return;
        }

        for (int i = 0; i < n; i++)
        {
            workArr[index] = i;
            GenerateVariationsWithRep(index + 1);
        }
    }

    private static void PrintCombo()
    {
        Console.WriteLine($"{++numberOfCombos}: [{string.Join(", ", workArr)}]");
    }
}

How to generate Combinations with repetition recursively in C#

//  1: [0, 0]
//  2: [0, 1]
//  3: [0, 2]
//  4: [0, 3]
//  5: [1, 1]
//  6: [1, 2]
//  7: [1, 3]
//  8: [2, 2]
//  9: [2, 3]
// 10: [3, 3]

using System;

public static class CombinationsWithRep
{
    private static int numberofCombos;
    private static int n;
    private static int k;
    private static int[] storageArr;

    public static void Main()
    {
        n = 4;
        k = 2;
        storageArr = new int[k];

        GenCombinationsWithRep();
    }

    private static void GenCombinationsWithRep(int index = 0, int element = 0)
    {
        if (index >= storageArr.Length)
        {
            PrintCombo();
            return;
        }

        for (int i = element; i < n; i++)
        {
            storageArr[index] = i;
            GenCombinationsWithRep(index + 1, i);
        }
    }

    private static void PrintCombo()
    {
        Console.WriteLine(
            "{0,3}: [{1}]",
            ++numberofCombos,
            string.Join(", ", storageArr));
    }
}

How to generate Variations without repetition recursively in C#

using System;
using System.Linq;

class VariationsWithoutRepetition
{
    const int k = 2;
    const int n = 4;

    static int[] arr = new int[k];
    static int[] free = Enumerable.Range(1, 4).ToArray();

    static void Main()
    {
        GenerateVariationsNoRepetitions(0);
    }

    static void GenerateVariationsNoRepetitions(int index)
    {
        if (index >= k)
        {
            PrintVariations();
        }
        else
        {
            for (int i = index; i < n; i++)
            {
                arr[index] = free[i];
                Swap(ref free[i], ref free[index]);
                GenerateVariationsNoRepetitions(index + 1);
                Swap(ref free[i], ref free[index]);
            }
        }
    }

    private static void Swap<T>(ref T v1, ref T v2)
    {
        T old = v1;
        v1 = v2;
        v2 = old;
    }

    static void PrintVariations()
    {
        Console.WriteLine("(" + string.Join(", ", arr) + ")");
    }
}


// result:
// (1, 2)
// (1, 3)
// (1, 4)
// (2, 1)
// (2, 3)
// (2, 4)
// (3, 2)
// (3, 1)
// (3, 4)
// (4, 2)
// (4, 3)
// (4, 1)