namespace timecomplexity;

using System;
using System.Diagnostics;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        int[] numbers = GenerateRandomNumbers(50_000);

        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();

        // TEST FUNCTION HERE!

        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;

        string elapsedTime = String.Format("{0:00}.{1:0000000} seconds",
        ts.Seconds, ts.Ticks % TimeSpan.TicksPerSecond);
        Console.WriteLine("RunTime " + elapsedTime);
    }

    // This method should iterates over an array (every element).
    static void SingleLoop(int[] numbers)
    {
    }

    // This method starts iterating an array, but it can end in any item...
    static void RandomLengthLoop(int[] numbers)
    {
    }

    // There should be nested loop (n steps in both loops)
    static void DoubleLoop(int[] numbers)
    {
    }

    // Can you create triple nested loop...
    static void TripleLoop(int[] numbers)
    {
    }

    // This one should include two separate loops, and other should be double loop, other O(n) loop (you can use two previous functions)
    static void CombinationOfLoops(int[] numbers)
    {
    }

    // And of course you can try to do constant time algorithm, which still uses a large array somehow
    static void ConstantTimeAlgorithm(int[] numbers)
    {
    }

    // This is O(2^n) algorithm. You can try to run this... Also, you can try to understand how this works.
    public static void GenerateSubsets(int n)
    {
        int[] subset = new int[n];
        GenerateSubsetsRecursive(subset, 0);
    }

    // this one is private, don't call this from main...
    private static void GenerateSubsetsRecursive(int[] subset, int index)
    {
        if (index == subset.Length)
        {
            // Print the subset
            Console.Write("{ ");
            for (int i = 0; i < subset.Length; i++)
            {
                Console.Write(subset[i] + " ");
            }
                Console.WriteLine("}");
                return;
        }

        // Include the current element
        subset[index] = 1;
        GenerateSubsetsRecursive(subset, index + 1);

        // Exclude the current element
        subset[index] = 0;
        GenerateSubsetsRecursive(subset, index + 1);
    }

    public static int[] GenerateRandomNumbers(int count)
    {
        Random random = new Random();
        int[] randomNumbers = new int[count];

        // Generate random numbers between 1 and 10 000
        for (int i = 0; i < count; i++)
        {
            randomNumbers[i] = random.Next(1, 10_000);
        }

        // Return the array
        return randomNumbers;
    }
}