using System;

namespace Мат_моделирование
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.WriteLine("Сделать первоначальное распределение по методу северо-западного угла в транспортной задаче с учетом преобразования исходной матрицы А в матрицу В по правилу:В = {mахл + 1}-А");
                uint r, c;//размерности матрицы и векторов
                while (true)//ввод потребителей(размерности по столбцам)
                {
                    try
                    {
                        Console.Write("Введите количество потребителей: ");
                        c = Convert.ToUInt32(Console.ReadLine());
                        if (c < 2)
                        {
                            Console.WriteLine("Потребителей должно быть не менее двух! Повторите ввод");
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch
                    {
                        Console.WriteLine("Введены некорректные данные!");
                    }
                }
                while (true)//ввод поставщиков(размерности по стокам)
                {
                    try
                    {
                        Console.Write("Введите количество поставщиков: ");
                         r= Convert.ToUInt32(Console.ReadLine());
                        if (r < 2)
                        {
                            Console.WriteLine("Поставщиков должно быть не менее двух! Повторите ввод");
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch
                    {
                        Console.WriteLine("Введены некорректные данные!");
                    }
                }
                int i = 0, j = 0;//переменные для циклов
                uint[,] matrxA = new uint[r, c];//матрица затрат
                Console.WriteLine("Ввод таблицы затрат на перевозку продукции:");//ввод данных в таблицу затрат
                for (i = 0; i < matrxA.GetLength(0); i++)
                {
                    for (j = 0; j < matrxA.GetLength(1); j++)
                    {

                        while (true)
                        {
                            try
                            {
                                Console.Write($"Введите стоимость перевозки от {i + 1} поставщика  к {j + 1} потребителю: ");
                                matrxA[i, j] = Convert.ToUInt32(Console.ReadLine());
                                break;
                            }
                            catch
                            {
                                Console.WriteLine("Введены некорректные данные!");
                            }
                        }

                    }
                    Console.WriteLine();
                }

                Console.WriteLine("Таблица затрат на перевозку продукции:");//вывод таблицы затрат на экран
                for (i = 0; i < matrxA.GetLength(0); i++)
                {
                    for (j = 0; j < matrxA.GetLength(1); j++)
                    {
                        Console.Write(matrxA[i, j] + "\t");
                    }
                    Console.WriteLine();
                }
                char otv;//переменная для диалога с пользователем
                //Изменение матрицы
                while (true)
                {
                    while (true)
                    {
                        try
                        {
                            Console.Write("\nХотите изменить данные о таблице?\nДа(любая клавиша)/Нет(N)\nОтвет: ");
                            otv = Convert.ToChar(Console.ReadLine());
                            break;
                        }
                        catch
                        {
                            Console.WriteLine("Введены некорректные данные!");
                        }
                    }
                    if (otv.Equals('n') || otv.Equals('т') || otv.Equals('N') || otv.Equals('Т'))
                    {
                        break;
                    }
                    else
                    {
                        Console.Write("Введите номер поставщика, затем номер потребителя, который вы хотите изменить\nОтвет:\n");
                        while (true)
                        {
                            i = Convert.ToInt32(Console.ReadLine());
                            j = Convert.ToInt32(Console.ReadLine());
                            if (i < c + 1 && j < r + 1)
                            {
                                while (true)
                                {
                                    try
                                    {
                                        Console.Write("Введите новое значение: ");
                                        uint temp = Convert.ToUInt32(Console.ReadLine());
                                        if (temp != 0)
                                        {
                                            Console.WriteLine($" Была изменена {i} {j} ячейка таблицы c {matrxA[i - 1, j - 1]} на {temp}");
                                            matrxA[i - 1, j - 1] = temp;
                                            break;
                                        }
                                        else
                                        {
                                            Console.WriteLine("Вы ввели нулевое значение! Повторите ввод");
                                        }
                                    }
                                    catch
                                    {
                                        Console.WriteLine("Введены некорректные данные!");
                                    }
                                }
                                break;
                            }
                            else
                            {
                                Console.WriteLine("Введенная размерность не соответствует матрице! Повторите ввод");
                            }
                        }
                    }
                }

                Console.Clear();
                uint max = 0;//нахождение максимальной затраты на перевозку
                for (i = 0; i < matrxA.GetLength(0); i++)
                {
                    for (j = 0; j < matrxA.GetLength(1); j++)
                    {
                        if (matrxA[i, j] > max)
                        {
                            max = matrxA[i, j];
                        }
                    }
                }
                Console.WriteLine($"Максимальная затрата на перевозку равна - {max}");
                uint[,] matrxB = new uint[r, c];//новая таблица затрат, пересчитанная по правилу, указанному в задании
                for (i = 0; i < matrxB.GetLength(0); i++)
                {
                    for (j = 0; j < matrxB.GetLength(1); j++)
                    {
                        matrxB[i, j] = (max + 1) - matrxA[i, j];
                    }

                }
                Console.WriteLine("Пересчитанная таблица затрат:");//вывод на экран новой таблицы затрат
                for (i = 0; i < matrxB.GetLength(0); i++)
                {
                    for (j = 0; j < matrxB.GetLength(1); j++)
                    {
                        Console.Write(matrxB[i, j] + "\t");
                    }
                    Console.WriteLine();
                }
                uint[] m = new uint[r];//вектор мощности поставщиков
                uint[] n = new uint[c];//вектор спроса потребителей
                uint valueM = 0, valueN = 0;
                while (true)
                {
                    Console.WriteLine("Ввод данных о количестве продукции поставщиков (m):");//ввод данных в вектор мощности поставщиков
                    for (i = 0; i < m.Length; i++)
                    {
                        while (true)
                        {
                            try
                            {
                                Console.Write($"Введите количество продукции у {i + 1} поставщика: ");
                                m[i] = Convert.ToUInt32(Console.ReadLine());
                                break;
                            }
                            catch
                            {
                                Console.WriteLine("Введены некорректные данные!");
                            }
                        }
                    }
                    Console.WriteLine("Ввод данных о запрашиваемом количестве продукции потребителями(n):");//ввод данных в вектор спроса потребителей
                    for (i = 0; i < n.Length; i++)
                    {
                        while (true)
                        {
                            try
                            {
                                Console.Write($"Введите количество необходимой продукции для {i + 1} потребителя: ");
                                n[i] = Convert.ToUInt32(Console.ReadLine());
                                break;
                            }
                            catch
                            {
                                Console.WriteLine("Введены некорректные данные!");
                            }
                        }
                    }
                    for (i = 0; i < m.Length; i++)
                    {
                        valueM += m[i];
                    }
                    for (i = 0; i < n.Length; i++)
                    {
                        valueN += n[i];
                    }
                    if (valueM == valueN)
                    {
                        break;
                    }
                    else//проверка на равенство суммы элементов векторов
                    {
                        Console.WriteLine("Вектор мощности (m) и cпроса (n) должны быть равны, повторите ввод!");
                        valueM = 0;
                        valueN = 0;
                    }
                }
                Console.WriteLine("Вектор мощности (m):");//вывод на экран
                for (i = 0; i < m.Length; i++)
                {
                    Console.Write($"{m[i]} ");
                }
                Console.WriteLine("\nВектор спроса (n):");//вывод на экран
                for (i = 0; i < n.Length; i++)
                {
                    Console.Write($"{n[i]} ");
                }

                Console.WriteLine("\nМатрица тарифов:");//вывод на экран матрицы и векторов
                Console.Write("  ");
                for (i = 0; i < n.Length; i++)
                {
                    Console.Write($"{n[i]} ");
                }
                Console.WriteLine();
                for (i = 0; i < matrxB.GetLength(0); i++)
                {
                    Console.Write($"{m[i]} ");
                    for (j = 0; j < matrxB.GetLength(1); j++)
                    {
                        Console.Write($"{matrxB[i, j]} ");
                    }
                    Console.WriteLine();
                }
                uint[,] raspr = new uint[r, c];//массив для распределения
                for (i = 0; i < raspr.GetLength(0); i++)
                {
                    for (j = 0; j < raspr.GetLength(1); j++)
                    {
                        raspr[i, j] = 0;
                    }
                }
                i = 0;
                j = 0;
                //алгоритм распределения
                while (i < r && j < c)
                {
                    if (n[j] > m[i])
                    {
                        raspr[i, j] = m[i];
                        n[j] -= m[i];
                        m[i] = 0;
                        i++;
                    }
                    else
                    {
                        raspr[i, j] = n[j];
                        m[i] -= n[j];
                        n[j] = 0;
                        j++;
                    }
                }
                Console.WriteLine();
                for (i = 0; i < raspr.GetLength(0); i++)
                {
                    for (j = 0; j < raspr.GetLength(1); j++)
                    {
                        Console.Write($"{raspr[i, j]} ");
                    }
                    Console.WriteLine();
                }
                uint F = 0;//нахождение функции распределения
                for (i = 0; i < raspr.GetLength(0); i++)
                {
                    for (j = 0; j < raspr.GetLength(1); j++)
                    {
                        if (raspr[i, j] != 0)
                        {
                            F += raspr[i, j] * matrxB[i, j];
                        }
                    }
                }
                Console.WriteLine($"F = {F} у.д.е");
                while (true)
                {
                    try
                    {
                        Console.Write("\nПовторить программу?\nДа(Y)/Нет(N)\nОтвет: ");
                        otv = Convert.ToChar(Console.ReadLine());
                        break;
                    }
                    catch
                    {
                        Console.WriteLine("Введены некорректные данные!");
                    }
                }
                if (!(otv.Equals('Y') || otv.Equals('y') || otv.Equals('н') || otv.Equals('Н')))
                {
                    break;
                }
                else if (!(otv.Equals('N') || otv.Equals('N') || otv.Equals('Т') || otv.Equals('т')))
                {
                    Console.Clear();
                }
                else
                {
                    Console.Clear();
                }
            }

        }
    }
}
