public void matrixMenu() { ConsoleKey action; // Переменная, в которую будет считываться нажатие клавиши int currItem = 1; // Текущий пункт меню do // Считываем нажатия, пока не будет ESC { windowM.newWindow(winWidth, winHeight); Console.CursorVisible = false; // Делаем курсор невидимым windowM.HeaderCenter("ОПЕРАЦИИ С МАТРИЦАМИ", winWidth, 2, ConsoleColor.Yellow); action = windowM.MenuSelect(menuItems, currItem, winWidth, 4); switch (action) { case ConsoleKey.D1: multiplyMatrixByNumber(); currItem = 1; break; case ConsoleKey.D2: addMatrixes(); currItem = 2; break; case ConsoleKey.D3: subtractMatrixes(); currItem = 3; break; case ConsoleKey.D4: multiplyMatrixes(); currItem = 4; break; case ConsoleKey.Escape: Console.WriteLine("ДО СВИДАНИЯ!"); break; default: break; // нажата любая другая клавиша - ничего не происходит } } while (action != ConsoleKey.Escape); } // public void matrixMenu()
public void printPascalTriangle() { int i, j; // вспомогательная переменная bool cursorVisibility; windowPT.newWindow(winWidth, winHeight); windowPT.HeaderCenter("ТРЕУГОЛЬНИК ПАСКАЛЯ", winWidth, 2, ConsoleColor.Yellow); Console.WriteLine(); cursorVisibility = Console.CursorVisible; Console.CursorVisible = true; level = correctInput.Parse("Введите количество уровней треугольника Паскаля", "Введите число", 1, 25, 0, 4); Console.WriteLine(); Console.CursorVisible = cursorVisibility; // Создаём зубчатый массив для ТП // Создаём массив уровней. Каждый элемент - это массив // для экономии памяти сделаем // количество элементов в каждом уровне ТП // в два раза меньше, чем номер уровня (если считать с 1) pT = new int[level][]; pTstring = new string[level]; #region заполнение треугольника Паскаля pT[0] = new int[1]; pT[0][0] = 1; // инициализируем элемент на 1-м уровне if (level >= 2) { pT[1] = new int[1]; pT[1][0] = 1; // инициализируем элемент на 2-м уровне } j = 0; // потребуется дальше, если не войдём по условию ниже. if (level > 2) { for (i = 2; i < level; i++) { // Создаём уровень // количество элементов в каждом уровне ТП // в два раза меньше, чем номер уровня (если считать с 1) // pos равен количеству элементов в массиве для очередного уровня // причём pos одинаковое для нечётного (если считать с 1) // и для следующего чётного уровня. // Выделяем соответствующий объём памяти pos = ((i + 1) / 2 + (i + 1) % 2); pT[i] = new int[pos]; pT[i][0] = 1; // инициализируем первый элемент уровня // Теперь надо инициализировать все остальные элементы, начиная со 2-ого по счёту // если уровень нечётный, то pos указывает на средний элемент (если считать с 1) // если чётный, то на первый самый большой элемент. // Поэтому мы не можем делать цикл ниже до pos, надо до предпоследнего элемента // for (j = 1; j < (pos - 1); j++) { pT[i][j] = pT[i - 1][j - 1] + pT[i - 1][j]; } // окончили цикл j == pos - 1 // это либо средний элемент (если в уровне нечётное кол-во элементов) // либо последний элемен, а следующий такой же (если в уровне чётное кол-во элементов) // но для 3 и 4 уровней цикл выше не работает, когда всего два элемента в массиве, // т.к. pos равен 2, pos - 1 равен 1, а j уже 1. if ((i + 1) % 2 == 1) // если нечётный уровень, когда считаем уровни с 1, { // то элемента pT[i - 1][pos] не существует pT[i][j] = pT[i - 1][j - 1] * 2; } else // если чётная, когда считаем уровни с 1, то существует, { // и мы как бы делаем последнюю итерацию цикла выше, но уже с j равным pos - 1 pT[i][j] = pT[i - 1][j - 1] + pT[i - 1][j]; } } // создание и заполнение массива for (i = 0; i < level; i++) } #endregion заполнение треугольника Паскаля #region вывод массива на экран // Чтобы вывести ТП, найдём длину самого длинного числа в ТП. // Это самое большое число, оно же самое последнее. longest = $"{pT[level - 1][j]}".Length; // если длина самого большого числа чётная, тогда добавляем 1 longest = ((longest % 2) == 0) ? ++longest : longest; int spaceLeft; // количество пробелов слева, чтобы число выводилось по центру поля string currString; // строковое представление текущего числа int half = longest / 2; // половина longest int s = 1; // расстояние между полями для вывода чисел int first; // координата первого числа уровня int next; // координаты начала поля следующего числа int offset; // сдвиг, чтобы ТП показывался по центру экрана int Y = 7; // координата первой строки // Сделаем количество символов в самом большом числе длиной поля // для вывод всех остальных чисел, кроме кайних 1. // Если longest чётное, то длина поля на 1 больше. // Будем помещать каждое число в центр такого поля. // Например, поле длиной 5 символов. Число 3 символа ".YYY." // Поле длиной 5 символов, число 2 символа ".YY..", если стоит слева от центральной вертикальной линии // или центральное число. И "..YY." если справа от центальной линии. // Ширина поля равна (half + 1 + half) // Расстояние между полями S сделаем 1 символ. Допустим, длина half это 3 символа. // Обозначим half как ... . Тогда формат вывода ТП будет таким // Не крайние единицы '1' - это центры полей для вывода соответствующих чисел ТП // 0 1 // 1 1...S...1 // 2 1...S...1...S...1 // 3 1...S...1...S...1...S...1 // 4 1...S...1...S...1...S...1...S...1 // тогда координата First на экране первого символа в N-ой строке (N считаемт от 0) // равна (1+half)*(level - N - 1) // координата единицы в 0-й строке равна (1+half)*(level - 1) // координата единицы в последней строке (1+half)* 0 = 0 // Найдём длину половинок слева и справа от центр // тогда координаты начала поля вывода любого следующих j-ого числа // Frist + (1 + half +S) + ((half + 1 + half) + S)* (j-1) // Формула учитывает, что координаты Х первого символа равны 0 (ноль) // Что индекс j начинается с 0, т.е. pT[...][0] = 1 offset = (((half + 1 + half + s) * (level - 1) + 1) < winWidth) ? (winWidth - ((half + 1 + half + s) * (level - 1) + 1)) / 2 : 5; if (level == 1) { Console.SetCursorPosition(offset, Y); Console.Write(pT[0][0]); } if (level >= 2) { i = 0; j = 0; first = (1 + half) * (level - i - 1); Console.SetCursorPosition(offset + first, Y + i); Console.Write(pT[i][j]); i = 1; j = 0; first = (1 + half) * (level - i - 1); Console.SetCursorPosition(offset + first, Y + i); Console.Write(pT[i][j]); j = 1; next = offset + first + (1 + half + s) + ((half + 1 + half) + s) * (j - 1); currString = $"{pT[i][j-1]}"; spaceLeft = (longest - currString.Length) / 2; Console.SetCursorPosition(next + spaceLeft, Y + i); Console.Write(pT[i][j - 1]); } if (level > 2) { for (i = 2; i < level; i++) { j = 0; first = (1 + half) * (level - i - 1); Console.SetCursorPosition(offset + first, Y + i); Console.Write(pT[i][j]); pos = ((i + 1) / 2 + (i + 1) % 2); for (j = 1; j < (pos - 1); j++) { next = offset + first + (1 + half + s) + ((half + 1 + half) + s) * (j - 1); currString = $"{pT[i][j]}"; spaceLeft = (longest - currString.Length) / 2; Console.SetCursorPosition(next + spaceLeft, Y + i); Console.Write(pT[i][j]); } // окончили цикл j == pos - 1 // это либо средний элемент (если в уровне нечётное кол-во элементов) // либо последний элемен, а следующий такой же (если в уровне чётное кол-во элементов) // но для 3 и 4 уровней цикл выше не работает, когда всего два элемента в массиве, // т.к. pos равен 2, pos - 1 равен 1, а j уже 1. // выводим центральный элемент (если уровень нечётный) // или 2 однаковых центральных элемента (если уровнь чётный) if ((i + 1) % 2 == 1) // если нечётный уровень, когда считаем уровни с 1, { // то элемента pT[i - 1][pos] не существует next = offset + first + (1 + half + s) + ((half + 1 + half) + s) * (j - 1); currString = $"{pT[i][j]}"; spaceLeft = (longest - currString.Length) / 2; Console.SetCursorPosition(next + spaceLeft, Y + i); Console.Write(pT[i][j]); } else // если чётная, когда считаем уровни с 1, то существует, { // и мы как бы делаем последнюю итерацию цикла выше, но уже с j равным pos - 1 next = offset + first + (1 + half + s) + ((half + 1 + half) + s) * (j - 1); currString = $"{pT[i][j]}"; spaceLeft = (longest - currString.Length) / 2; Console.SetCursorPosition(next + spaceLeft, Y + i); Console.Write(pT[i][j]); j++; next = offset + first + (1 + half + s) + ((half + 1 + half) + s) * (j - 1); currString = $"{pT[i][j-1]}"; spaceLeft = (longest - currString.Length) / 2; spaceLeft += (currString.Length % 2 == 0) ? 1 : 0; Console.SetCursorPosition(next + spaceLeft, Y + i); Console.Write(pT[i][j - 1]); } j++; for (int k = (pos - 1 - 1); k >= 0; k--) { next = offset + first + (1 + half + s) + ((half + 1 + half) + s) * (j - 1); currString = $"{pT[i][k]}"; spaceLeft = (longest - currString.Length) / 2; spaceLeft += (currString.Length % 2 == 0) ? 1: 0; Console.SetCursorPosition(next + spaceLeft, Y + i); Console.Write(pT[i][k]); j++; } // выводим правое крыло } // for i } Console.WriteLine(); #endregion вывод массива на экран Console.WriteLine(); Console.WriteLine("Нажмите любую клавишу"); Console.ReadKey(); }
static void Main(string[] args) { #region Задание 1. // Заказчик просит вас написать приложение по учёту финансов // и продемонстрировать его работу. // Суть задачи в следующем: // Руководство фирмы по 12 месяцам ведет учет расходов и поступлений средств. // За год получены два массива – расходов и поступлений. // Определить прибыли по месяцам // Количество месяцев с положительной прибылью. // Добавить возможность вывода трех худших показателей по месяцам, с худшей прибылью, // если есть несколько месяцев, в которых худшая прибыль совпала - вывести их все. // Организовать дружелюбный интерфейс взаимодействия и вывода данных на экран // Пример // // Месяц Доход, тыс. руб. Расход, тыс. руб. Прибыль, тыс. руб. // 1 100 000 80 000 20 000 // 2 120 000 90 000 30 000 // 3 80 000 70 000 10 000 // 4 70 000 70 000 0 // 5 100 000 80 000 20 000 // 6 200 000 120 000 80 000 // 7 130 000 140 000 -10 000 // 8 150 000 65 000 85 000 // 9 190 000 90 000 100 000 // 10 110 000 70 000 40 000 // 11 150 000 120 000 30 000 // 12 100 000 80 000 20 000 // // Худшая прибыль в месяцах: 7, 4, 1, 5, 12 // Месяцев с положительной прибылью: 10 #endregion #region * Задание 2 // Заказчику требуется приложение строящее первых N строк треугольника паскаля. N < 25 // // При N = 9. Треугольник выглядит следующим образом: // 1 // 1 1 // 1 2 1 // 1 3 3 1 // 1 4 6 4 1 // 1 5 10 10 5 1 // 1 6 15 20 15 6 1 // 1 7 21 35 35 21 7 1 // // // Простое решение: // 1 // 1 // 1 2 // 1 3 // 1 4 6 // 1 5 10 // 1 6 15 20 15 6 1 // 1 7 21 35 35 21 7 1 // // Справка: https://ru.wikipedia.org/wiki/Треугольник_Паскаля #endregion #region * Задание 3.1 // Заказчику требуется приложение позволяющщее умножать математическую матрицу на число // Справка https://ru.wikipedia.org/wiki/Матрица_(математика) // Справка https://ru.wikipedia.org/wiki/Матрица_(математика)#Умножение_матрицы_на_число // Добавить возможность ввода количество строк и столцов матрицы и число, // на которое будет производиться умножение. // Матрицы заполняются автоматически. // Если по введённым пользователем данным действие произвести невозможно - сообщить об этом // // Пример // // | 1 3 5 | | 5 15 25 | // 5 х | 4 5 7 | = | 20 25 35 | // | 5 3 1 | | 25 15 5 | // // // ** Задание 3.2 // Заказчику требуется приложение позволяющщее складывать и вычитать математические матрицы // Справка https://ru.wikipedia.org/wiki/Матрица_(математика) // Справка https://ru.wikipedia.org/wiki/Матрица_(математика)#Сложение_матриц // Добавить возможность ввода количество строк и столцов матрицы. // Матрицы заполняются автоматически // Если по введённым пользователем данным действие произвести невозможно - сообщить об этом // // Пример // | 1 3 5 | | 1 3 4 | | 2 6 9 | // | 4 5 7 | + | 2 5 6 | = | 6 10 13 | // | 5 3 1 | | 3 6 7 | | 8 9 8 | // // // | 1 3 5 | | 1 3 4 | | 0 0 1 | // | 4 5 7 | - | 2 5 6 | = | 2 0 1 | // | 5 3 1 | | 3 6 7 | | 2 -3 -6 | // // *** Задание 3.3 // Заказчику требуется приложение позволяющщее перемножать математические матрицы // Справка https://ru.wikipedia.org/wiki/Матрица_(математика) // Справка https://ru.wikipedia.org/wiki/Матрица_(математика)#Умножение_матриц // Добавить возможность ввода количество строк и столцов матрицы. // Матрицы заполняются автоматически // Если по введённым пользователем данным действие произвести нельзя - сообщить об этом // // | 1 3 5 | | 1 3 4 | | 22 48 57 | // | 4 5 7 | х | 2 5 6 | = | 35 79 95 | // | 5 3 1 | | 3 6 7 | | 14 36 45 | // // // | 4 | // | 1 2 3 | х | 5 | = | 32 | // | 6 | #endregion ConsoleKey action; // Переменная, в которую будет считываться нажатие клавиши #region example of key reading //do //{ // Console.WriteLine("Press a key, together with Alt, Ctrl, or Shift."); // Console.WriteLine("Press Esc to exit."); // action = Console.ReadKey(true); // StringBuilder output = new StringBuilder( // String.Format("You pressed {0}", action.Key.ToString())); // bool modifiers = false; // if ((action.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt) // { // output.Append(", together with " + ConsoleModifiers.Alt.ToString()); // modifiers = true; // } // if ((action.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control) // { // if (modifiers) // { // output.Append(" and "); // } // else // { // output.Append(", together with "); // modifiers = true; // } // output.Append(ConsoleModifiers.Control.ToString()); // } // if ((action.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift) // { // if (modifiers) // { // output.Append(" and "); // } // else // { // output.Append(", together with "); // modifiers = true; // } // output.Append(ConsoleModifiers.Shift.ToString()); // } // output.Append("."); // Console.WriteLine(output.ToString()); // Console.WriteLine(); //} while (action.Key != ConsoleKey.Escape); #endregion example of key reading Console.CursorVisible = false; // Делаем курсор невидимым var winHeight = 20; // Высота экрана (для меню) 20 строк var winWidth = 80; // Ширина экрана (для меню) 80 строк int currItem = 1; // текущая позиция меню WindowOutput window; FinancialReport financialReport; PascalTriangle pascalTriangle; Matrix matrix; MenuItem[] menuItems = // Пункты меню для вывода на экран { new MenuItem { itemKey = ConsoleKey.D1, itemName = "1. ФИНАНСОВЫЙ УЧЁТ В КОМПАНИИ" }, new MenuItem { itemKey = ConsoleKey.D2, itemName = "2. ТРЕУГОЛЬНИК ПАСКАЛЯ" }, new MenuItem { itemKey = ConsoleKey.D3, itemName = "3. ОПЕРАЦИИ С МАТРИЦАМИ" }, new MenuItem { itemKey = ConsoleKey.Escape, itemName = "ESC ВЫХОД" } }; window = new WindowOutput(winWidth, winHeight); financialReport = new FinancialReport(); pascalTriangle = new PascalTriangle(); matrix = new Matrix(); do // Считываем нажатия, пока не будет ESC { window.newWindow(winWidth, winHeight); window.HeaderCenter("Домашняя работа №4", winWidth, 2, ConsoleColor.Yellow); window.HeaderCenter("Дмитрий Мельников", winWidth, 3, ConsoleColor.Yellow); action = window.MenuSelect(menuItems, currItem, winWidth, 5); switch (action) { case ConsoleKey.D1: financialReport.financialReportMenu(); currItem = 1; break; case ConsoleKey.D2: pascalTriangle.printPascalTriangle(); currItem = 2; break; case ConsoleKey.D3: matrix.matrixMenu(); currItem = 3; break; case ConsoleKey.Escape: break; default: break; // нажата любая другая клавиша - ничего не происходит } } while (action != ConsoleKey.Escape); }