using ConsoleApp1;
using System.Data.Common;
using System.Diagnostics;
internal class Program
{
    private static void Main(string[] args)
    {
        var value = new int[3] {100, 300, 500 };

        foreach(var i in value)
        {
            var a = CreateMatrix(i, i);
            var b = CreateMatrix(i, i);

            List<long> times = new() {};
            Console.WriteLine("Для пяти потоков: ");
            for (int j = 1; j <= 5; j++)
            {
                var sw = new Stopwatch();
                sw.Start();

                Calculate(a, j);

                sw.Stop();
                times.Add(sw.ElapsedTicks);
            }
            Console.WriteLine("Количество тиков для вычисления матрицы стороной "+i+": "+string.Join("\t", times));

            Console.WriteLine("Для десяти потоков: ");
            for (int j = 1; j <= 10; j++)
            {
                var sw = new Stopwatch();
                sw.Start();

                Calculate(a, j);

                sw.Stop();
                times.Add(sw.ElapsedTicks);
            }
            Console.WriteLine("Количество тиков для вычисления матрицы стороной " + i + ": " + string.Join("\t", times));

        }
    }

    private static int[,] CreateMatrix(int x, int y)
    {
        var rnd = new Random();

        var res = new int[y, x];

        for (int i = 0; i < y; i++)
        {
            for (int j = 0; j < x; j++)
            {
                res[i, j] = rnd.Next(0, 100);
            }
        }
        return res;
    }

    private static double Calculate(int[,] matrix, int maxTask)
    {
        double res = 0;

        var semaphore = new SemaphoreSlim(maxTask, maxTask);

        for (var j = 0; j < matrix.GetLength(0) - 1; j++)
        {
            _ = Task.Run(() =>
            {
                try
                {
                    semaphore.Wait();
                    res += (j % 2 == 1 ? 1 : -1) * matrix[1, j] *
                     matrix.CreateMatrixWithoutColumn(j).
                     CreateMatrixWithoutRow(1).CalculateDeterminant();
                }
                finally { semaphore.Release(); }
            });

        }

        semaphore.Wait(maxTask);
        return res;
    }
}