#include <stdio.h>

const int maxSize = 20;

void waitEnter()
{
    printf("\n\n\x1B[32mНажмите Enter, чтобы продолжить...\x1B[0m\n");

    char prev = 0;

    while (1)
    {
        char c = getchar();

        if (c == '\n' && prev == c)
        {
            break;
        }

        prev = c;
    }

    printf("\e[1;1H\e[2J");
}

void generateMatr(int matr[maxSize][maxSize], int *n)
{
    do
    {
        printf("Введите размер матрицы [i, i]: ");
        scanf("%d", &*n);
    } while (n <= 0);

    for (int i = 0; i < *n; i++)
        for (int j = 0; j < *n; j++)
            matr[i][j] = i * *n + j;
}
void inputMatr(int matr[maxSize][maxSize], int *n)
{
    do
    {
        printf("Введите размер матрицы [i, i]: ");
        scanf("%d", &*n);
    } while (*n <= 0);

    printf("Введите значения:\n");
    for (int i = 0; i < *n; i++)
        for (int j = 0; j < *n; j++)
            scanf("%d", &matr[i][j]);
}

void outputMatr(int matr[maxSize][maxSize], int n)
{
    printf("\x1B[31mВывод матрицы [%d][%d]:\n", n, n);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            printf("%3d ", matr[i][j]);
        printf("\n");
    }
    printf("\x1B[0m\n\n\n");
}

int sumOfLowerTriangle(int matr[maxSize][maxSize], int n)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
        for (int j = n - i; j < i; j++)
            sum += matr[i][j];

    return sum;
}
int sumOfUpperTriangle(int matr[maxSize][maxSize], int n)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n - i - 1; j++)
            sum += matr[i][j];

    return sum;
}
int sumOfRightTriangle(int matr[maxSize][maxSize], int n)
{
    int sum = 0;
    for (int j = 0; j < n; j++)
        for (int i = n - j; i < j; i++)
            sum += matr[i][j];

    return sum;
}
int sumOfLeftTriangle(int matr[maxSize][maxSize], int n)
{
    int sum = 0;
    for (int j = 0; j < n; j++)
        for (int i = j + 1; i < n - j - 1; i++)
            sum += matr[i][j];

    return sum;
}

int minElUpSideDiag(int matr[maxSize][maxSize], int n)
{
    int minEl = matr[0][0];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n - i - 1; j++)
            if (matr[i][j] < minEl)
                minEl = matr[i][j];

    return minEl;
}

int minElUpTriangle(int matr[maxSize][maxSize], int n)
{
    int minEl = matr[0][0];
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n - i - 1; j++)
            if (matr[i][j] < minEl)
                minEl = matr[i][j];

    return minEl;
}

void reverseMainDiag(int matr[maxSize][maxSize], int n)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            if (i == j)
                printf("%3d ", matr[n - i - 1][n - j - 1]);
            else
                printf("%3d ", matr[i][j]);
        printf("\n");
    }
}

void replaceUpiDown(int matr[maxSize][maxSize], int n)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            if ((j < n - i - 1 && j > i) || (j > n - i - 1 && j < i))
                printf("%3d ", matr[n - i - 1][j]);
            else
                printf("%3d ", matr[i][j]);
        printf("\n");
    }
}

void totateBy90degree(int matr[maxSize][maxSize], int n)
{
    for (int j = 0; j < n; j++)
    {
        for (int i = n - 1; i >= 0; i--)
            printf("%3d ", matr[i][j]);
        printf("\n");
    }
}

void flipMSideDiag(int matr[maxSize][maxSize], int n)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            if (j != n - i - 1)
                printf("%3d ", matr[n - i - 1][n - j - 1]);
            else
                printf("%3d ", matr[i][j]);
        printf("\n");
    }
}

void task404()
{
    printf("Такой задачи нет :(\n");
}

int main()
{
    int matr[maxSize][maxSize];
    int n;
    generateMatr(matr, &n);
    // inputMatr(matr, &n);
    printf("\e[1;1H\e[2J");

    while (1 > 0)
    {
        outputMatr(matr, n);

        printf("Что хочешь сделать с матрицей?\n\n");
        printf(
            "\
1 — Сумма треугольника\n\
2 — Минимальный элемент над помобчной диагональю\n\
3 — Минимальный элемент верхнего треуг\n\
4 — Поменять зеркально элементы главной диагонали\n\
5 — Поменять местами верхний и нижний треугольники\n\
6 — Повернуть матрицу на 90 градусов по часовой стрелке\n\
7 — Отзеркалить матрицу относительно побочной диагонали\n\
");

        int zad;
        do
        {
            if (zad <= 0)
                printf("Введите номер из меню!\n");
            scanf("%d", &zad);
        } while (zad <= 0);

        printf("\e[1;1H\e[2J");
        outputMatr(matr, n);

        switch (zad)
        {
        case 1:
            printf("Сумму какого треугольника?\n\n");
            printf(
                "\
    1 — Левого\n\
    2 — Правого\n\
    3 — Нижнего\n\
    4 — Верхнего\n\
    ");

            int triangle;
            do
            {
                if (triangle <= 0)
                    printf("Введите номер из меню!\n");
                scanf("%d", &triangle);
            } while (triangle <= 0);

            switch (triangle)
            {
            case 1:
                printf("Сумма левого треуг = %d\n", sumOfLeftTriangle(matr, n));
                break;
            case 2:
                printf("Сумма правого треуг = %d\n", sumOfRightTriangle(matr, n));
                break;
            case 3:
                printf("Сумма нижнего треуг = %d\n", sumOfLowerTriangle(matr, n));
                break;
            case 4:
                printf("Сумма верхнего треуг = %d\n", sumOfUpperTriangle(matr, n));
                break;
            default:
                task404();
                break;
            }
            break;
        case 2:
            printf("Минимальный элемент над помобчной диагональю = %d\n", minElUpSideDiag(matr, n));
            break;
        case 3:
            printf("Минимальный элемент верхнего треуг = %d\n", minElUpTriangle(matr, n));
            break;
        case 4:
            printf("Поменять зеркально элементы главной диагонали:\n");
            reverseMainDiag(matr, n);
            break;
        case 5:
            printf("Поменять местами верхний и нижний треугольники:\n");
            replaceUpiDown(matr, n);
            break;
        case 6:
            printf("Повернуть матрицу на 90 градусов по часовой стрелке:\n");
            totateBy90degree(matr, n);
            break;
        case 7:
            printf("Отзеркалить матрицу относительно побочной диагонали:\n");
            flipMSideDiag(matr, n);
            break;

        default:
            task404();
            break;
        }
        waitEnter();
    }
}