Загрузка данных


#pragma once
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#include <iomanip>
#include <algorithm>
#include <math.h>
#include <locale.h>
#include <cmath>
#include <limits>
#include <intrin.h>
#include <bitset>
#include <queue>
#include <utility>
#include <string>
#include <cstdlib>

using namespace std;

// Макросы
#define ClearCin cin.clear(); cin.ignore(cin.rdbuf()->in_avail())
#define SPACEBACK(n) for(int ii=0; ii<n; ii++) cout << " "; for(int ii=0; ii<n; ii++) cout << "\b"
#define ENDL cout << endl

// Макросы для задания 3
#define Hi(x) ( sizeof(x)==1 ? 0 : ((x) >> (8*(sizeof(x)-1))) )
#define Lo(x) ((x) & 0xFF)
#define Swap(x) ( \
    sizeof(x)==1 ? (x) : \
    sizeof(x)==2 ? _byteswap_ushort((unsigned short)(x)) : \
    sizeof(x)==4 ? _byteswap_ulong((unsigned long)(x)) : \
                  _byteswap_uint64((unsigned long long)(x)) )

// ========== ПРОТОТИПЫ ФУНКЦИЙ ВВОДА С ESC ==========
bool ReadStringWithESC(std::string& out);
bool ReadDoubleWithESC(double& val);
bool ReadIntWithESC(int& val);

// ========== ПРОТОТИПЫ ОСНОВНЫХ ФУНКЦИЙ ==========
void SetCursorPosition(short row, short col);
COORD GetCursorPosition();
void info();
void SetColor(int text, int bg);
int Lab1_Static();
int Lab2_Dynamic();
int Labirint();
int MASKA();
int Macros();
int CIPHER();

#include "Header.h"

// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ==========
void SetCursorPosition(short row, short col) {
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD position = { col, row };
    SetConsoleCursorPosition(hStdOut, position);
}

COORD GetCursorPosition() {
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    return csbi.dwCursorPosition;
}

void info() {
    cout << "Зажигин А.К. группа 1бИВТн5 вариант 9\n\n";
}

void SetColor(int text, int bg) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (bg << 4) | text);
}

// ========== ФУНКЦИИ ВВОДА С ESC (ОТ ДРУГА) ==========
bool ReadStringWithESC(std::string& out) {
    out.clear();
    while (true) {
        if (_kbhit()) {
            int ch = _getch();
            if (ch == 27) {
                cout << endl << endl << "Аварийный выход через ESC!" << endl;
                system("pause");
                return false;
            }
            if (ch == 13) {
                cout << '\n';
                return true;
            }
            if (ch == 8) {
                if (!out.empty()) {
                    out.pop_back();
                    cout << "\b \b";
                }
            }
            else if (ch == 0 || ch == 224) {
                _getch();
            }
            else if ((ch >= 32 && ch <= 126) || (ch >= 128 && ch <= 255)) {
                out += static_cast<char>(ch);
                cout << static_cast<char>(ch);
            }
        }
    }
}

bool ReadIntWithESC(int& val) {
    std::string s;
    COORD errorPos = { 0, 0 };
    bool errorShown = false;

    while (true) {
        if (!ReadStringWithESC(s)) return false;
        if (s.empty()) continue;

        try {
            val = std::stoi(s);
            return true;
        }
        catch (...) {
            if (!errorShown) {
                cout << endl;
                errorPos = GetCursorPosition();
                errorShown = true;
            }
            SetCursorPosition(errorPos.Y, errorPos.X);
            SPACEBACK(50);
            cout << "Ошибка! Введите целое число: ";
            s.clear();
        }
    }
}

bool ReadDoubleWithESC(double& val) {
    std::string s;
    COORD errorPos = { 0, 0 };
    bool errorShown = false;

    while (true) {
        if (!ReadStringWithESC(s)) return false;
        if (s.empty()) continue;

        try {
            val = std::stod(s);
            return true;
        }
        catch (...) {
            if (!errorShown) {
                cout << endl;
                errorPos = GetCursorPosition();
                errorShown = true;
            }
            SetCursorPosition(errorPos.Y, errorPos.X);
            SPACEBACK(50);
            cout << "Ошибка! Введите число: ";
            s.clear();
        }
    }
}

// ========== ЛАБОРАТОРНАЯ РАБОТА 1 (СТАТИЧЕСКИЙ МАССИВ) ==========
int Lab1_Static() {
    system("cls");
    info();

    cout << "===========================================================\n";
    cout << "Лабораторная работа 1 (Статический массив)\n";
    cout << "Задан массив y[1], y[2], ..., y[10].\n";
    cout << "Если индекс ymin меньше 5, то заменить в исходном массиве\n";
    cout << "отрицательные y[i] на ymin.\n";
    cout << "===========================================================\n\n";

    const int SIZE = 10;
    int arr[SIZE];

    cout << "Введите 10 целых чисел (ESC - аварийный выход):\n";
    COORD coord = GetCursorPosition();

    for (int i = 0; i < SIZE; i++) {
        SetCursorPosition(coord.Y, coord.X);
        SPACEBACK(50);
        cout << "y[" << i + 1 << "] = ";

        int val;
        if (!ReadIntWithESC(val)) return 0;
        arr[i] = val;
    }

    ENDL;
    cout << "Введенные числа:" << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << "y[" << i + 1 << "] = " << arr[i];
        if (i < SIZE - 1) cout << ", ";
        else cout << endl;
    }
    ENDL;

    // Поиск минимального элемента и его индекса
    int minIndex = 0;
    for (int i = 1; i < SIZE; i++) {
        if (arr[i] < arr[minIndex]) {
            minIndex = i;
        }
    }

    cout << "Минимальный элемент: y[" << minIndex + 1 << "] = " << arr[minIndex] << endl;
    cout << "Индекс ymin = " << minIndex + 1 << endl;
    ENDL;

    // Если индекс ymin меньше 5, заменяем отрицательные элементы на ymin
    if (minIndex + 1 < 5) {
        cout << "Индекс ymin меньше 5, выполняем замену..." << endl;
        for (int i = 0; i < SIZE; i++) {
            if (arr[i] < 0) {
                arr[i] = arr[minIndex];
            }
        }

        cout << "Массив после замены отрицательных элементов на ymin:" << endl;
        for (int i = 0; i < SIZE; i++) {
            cout << "y[" << i + 1 << "] = " << arr[i];
            if (i < SIZE - 1) cout << ", ";
            else cout << endl;
        }
    } else {
        cout << "Индекс ymin >= 5, замена не требуется." << endl;
    }

    ENDL;
    cout << "Нажмите любую клавишу для возврата в меню...";
    _getch();
    return 0;
}

// ========== ЛАБОРАТОРНАЯ РАБОТА 2 (ДИНАМИЧЕСКИЙ МАССИВ) ==========
int Lab2_Dynamic() {
    system("cls");
    info();

    cout << "===========================================================\n";
    cout << "Лабораторная работа 2 (Динамический массив)\n";
    cout << "Задан массив y[1], y[2], ..., y[N].\n";
    cout << "Если индекс ymin меньше 5, то заменить в исходном массиве\n";
    cout << "отрицательные y[i] на ymin.\n";
    cout << "===========================================================\n\n";

    int SIZE;
    cout << "Введите количество элементов массива N: ";
    if (!ReadIntWithESC(SIZE)) return 0;
    while (SIZE <= 0) {
        cout << "Ошибка! Введите положительное число: ";
        if (!ReadIntWithESC(SIZE)) return 0;
    }

    int* arr = new int[SIZE];

    cout << "\nВведите " << SIZE << " целых чисел (ESC - выход):" << endl;
    COORD coord = GetCursorPosition();

    for (int i = 0; i < SIZE; i++) {
        SetCursorPosition(coord.Y, coord.X);
        SPACEBACK(50);
        cout << "y[" << i + 1 << "] = ";

        if (!ReadIntWithESC(arr[i])) {
            delete[] arr;
            return 0;
        }
    }

    ENDL;
    cout << "Введенные числа:" << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << "y[" << i + 1 << "] = " << arr[i];
        if (i < SIZE - 1) cout << ", ";
        else cout << endl;
    }
    ENDL;

    // Поиск минимального элемента и его индекса
    int minIndex = 0;
    for (int i = 1; i < SIZE; i++) {
        if (arr[i] < arr[minIndex]) {
            minIndex = i;
        }
    }

    cout << "Минимальный элемент: y[" << minIndex + 1 << "] = " << arr[minIndex] << endl;
    cout << "Индекс ymin = " << minIndex + 1 << endl;
    ENDL;

    if (minIndex + 1 < 5) {
        cout << "Индекс ymin меньше 5, выполняем замену..." << endl;
        for (int i = 0; i < SIZE; i++) {
            if (arr[i] < 0) {
                arr[i] = arr[minIndex];
            }
        }

        cout << "Массив после замены отрицательных элементов на ymin:" << endl;
        for (int i = 0; i < SIZE; i++) {
            cout << "y[" << i + 1 << "] = " << arr[i];
            if (i < SIZE - 1) cout << ", ";
            else cout << endl;
        }
    } else {
        cout << "Индекс ymin >= 5, замена не требуется." << endl;
    }

    delete[] arr;
    arr = nullptr;

    ENDL;
    cout << "Нажмите любую клавишу для возврата в меню...";
    _getch();
    return 0;
}

// ========== ЛАБИРИНТ ==========
int Labirint() {
    system("cls");
    info();

    cout << "===========================================================\n";
    cout << "Лабиринт 32x32\n";
    cout << "===========================================================\n";
    cout << "Управление:\n";
    cout << "  стрелки - движение\n";
    cout << "  F5 - показать/скрыть путь\n";
    cout << "  ESC - выход\n";
    cout << "===========================================================\n\n";

    unsigned int map[32] = {
        0b10111111111111111111111111111111,
        0b10000000000000000000000000000001,
        0b10111111111111111111111111111101,
        0b10000000100000000000001000000001,
        0b10111110101111111111110101111101,
        0b10000010100000000000000101000001,
        0b10111010101110111011101010111011,
        0b10001000100010001000100010001001,
        0b11101011111011101110111110101111,
        0b10001000001000100010000000100001,
        0b10111011101110111011101110111011,
        0b10000010000000100000000001000001,
        0b11111110111111101111111101111111,
        0b10000000100000000000001000000001,
        0b10111111101111111111110111111101,
        0b10000000001000000000000000000001,
        0b11101111111011101110111111101111,
        0b10001000001000100010000000100001,
        0b10111011101110111011101110111011,
        0b10000010000000100000000001000001,
        0b11111110111111101111111101111111,
        0b10000000100000000000001000000001,
        0b10111111101111111111110111111101,
        0b10000000001000000000000000000001,
        0b11101111111011101110111111101111,
        0b10001000001000100010000000100001,
        0b10111011101110111011101110111011,
        0b10000010000000100000000001000001,
        0b11111110111111101111111101111111,
        0b10000000100000000000001000000011,
        0b10111111111111111111111111111111,
        0b10111111111111111111111111111111
    };

    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    const int WHITE = 15 << 4;
    const int BLACK = 0;
    const int RED = BACKGROUND_RED | BACKGROUND_INTENSITY;
    const int GREEN = BACKGROUND_GREEN | BACKGROUND_INTENSITY;

    int bugR = 0, bugC = 1;
    int exitR = 31, exitC = 1;

    auto isWall = [&](int r, int c) { return (map[r] >> (31 - c)) & 1; };

    if (isWall(exitR, exitC)) { exitR = 31; exitC = 30; }

    COORD topLeft = GetCursorPosition();

    for (int r = 0; r < 32; r++) {
        for (int c = 0; c < 32; c++) {
            SetConsoleTextAttribute(h, isWall(r, c) ? BLACK : WHITE);
            cout << "  ";
        }
        cout << endl;
    }

    SetCursorPosition(topLeft.Y + exitR, topLeft.X + exitC * 2);
    SetConsoleTextAttribute(h, WHITE | 10);
    cout << "ВХ";
    SetConsoleTextAttribute(h, 7);

    SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
    SetConsoleTextAttribute(h, RED);
    cout << "  ";
    SetConsoleTextAttribute(h, 7);

    unsigned int path[32] = {0};
    bool pathShown = false;
    bool gameOver = false;

    while (!gameOver) {
        unsigned char key = _getch();
        if (key == 27) {
            return 0;
        }

        if (key == 0) {
            key = _getch();
            if (key == 63) {
                if (!pathShown) {
                    memset(path, 0, sizeof(path));

                    int visited[32][32] = {0};
                    int prevR[32][32], prevC[32][32];
                    for (int i = 0; i < 32; i++)
                        for (int j = 0; j < 32; j++)
                            prevR[i][j] = prevC[i][j] = -1;

                    queue<pair<int, int>> q;
                    q.push({bugR, bugC});
                    visited[bugR][bugC] = 1;

                    bool found = false;
                    while (!q.empty() && !found) {
                        pair<int, int> cur = q.front(); q.pop();
                        int r = cur.first, c = cur.second;

                        int dr[] = {1,0,-1,0}, dc[] = {0,1,0,-1};
                        for (int i = 0; i < 4; i++) {
                            int nr = r + dr[i], nc = c + dc[i];
                            if (nr>=0 && nr<32 && nc>=0 && nc<32 && !isWall(nr,nc) && !visited[nr][nc]) {
                                visited[nr][nc] = 1;
                                prevR[nr][nc] = r;
                                prevC[nr][nc] = c;
                                if (nr == exitR && nc == exitC) { found = true; break; }
                                q.push({nr, nc});
                            }
                        }
                    }

                    if (found) {
                        int r = exitR, c = exitC;
                        while (!(r == bugR && c == bugC)) {
                            path[r] |= 1 << (31 - c);
                            SetConsoleTextAttribute(h, GREEN);
                            SetCursorPosition(topLeft.Y + r, topLeft.X + c * 2);
                            cout << "  ";
                            int pr = prevR[r][c], pc = prevC[r][c];
                            r = pr; c = pc;
                        }
                        path[bugR] |= 1 << (31 - bugC);
                        SetConsoleTextAttribute(h, GREEN);
                        SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
                        cout << "  ";
                    }

                    SetConsoleTextAttribute(h, RED);
                    SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
                    cout << "  ";
                    SetConsoleTextAttribute(h, 7);

                    SetCursorPosition(topLeft.Y + 33, 0);
                    SetConsoleTextAttribute(h, BLACK | 14);
                    cout << (found ? "ПУТЬ НАЙДЕН!          " : "ПУТИ НЕТ.              ");
                    SetConsoleTextAttribute(h, 7);

                    pathShown = found;
                } else {
                    for (int r = 0; r < 32; r++)
                        for (int c = 0; c < 32; c++)
                            if (path[r] & (1 << (31 - c))) {
                                SetConsoleTextAttribute(h, WHITE);
                                SetCursorPosition(topLeft.Y + r, topLeft.X + c * 2);
                                cout << "  ";
                            }
                    memset(path, 0, sizeof(path));
                    pathShown = false;

                    SetConsoleTextAttribute(h, RED);
                    SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
                    cout << "  ";
                    SetConsoleTextAttribute(h, 7);
                }
                continue;
            }
        }

        if (key == 224) {
            key = _getch();
            int newR = bugR, newC = bugC;
            switch (key) {
                case 75: newC--; break;
                case 77: newC++; break;
                case 72: newR--; break;
                case 80: newR++; break;
                default: continue;
            }

            if (newR<0 || newR>=32 || newC<0 || newC>=32 || isWall(newR, newC)) {
                Beep(750,300);
                continue;
            }

            SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
            if (pathShown && (path[bugR] & (1 << (31 - bugC))))
                SetConsoleTextAttribute(h, GREEN);
            else
                SetConsoleTextAttribute(h, WHITE);
            cout << "  ";

            bugR = newR; bugC = newC;

            SetCursorPosition(topLeft.Y + bugR, topLeft.X + bugC * 2);
            SetConsoleTextAttribute(h, RED);
            cout << "  ";

            if (bugR == exitR && bugC == exitC) {
                SetConsoleTextAttribute(h, BLACK | 14);
                SetCursorPosition(topLeft.Y + 33, 0);
                cout << "ПОЗДРАВЛЯЕМ! ВЫ ВЫШЛИ!";
                Beep(1000,500);
                gameOver = true;
            }
            SetConsoleTextAttribute(h, 7);
        }
    }

    cout << "\n\nНажмите любую клавишу для возврата в меню...";
    _getch();
    return 0;
}

// ========== МАСКА ==========
int MASKA() {
    system("cls");
    info();

    cout << "===========================================================\n";
    cout << "Маска\n";
    cout << "Задан массив y[1], y[2], ..., y[20].\n";
    cout << "Определить, какие значения массива соответствуют маске (01010100).\n";
    cout << "===========================================================\n\n";

    short mas[20] = {};
    unsigned short maska = 0x54;

    cout << "Введите 20 целых чисел (ESC - выход):" << endl;

    COORD coord = GetCursorPosition();

    for (int i = 0; i < 20; i++) {
        SetCursorPosition(coord.Y, coord.X);
        SPACEBACK(50);
        cout << "y[" << i + 1 << "] = ";

        int val;
        if (!ReadIntWithESC(val)) return 0;
        mas[i] = (short)val;
    }

    ENDL;
    cout << "Введенные числа:" << endl;
    for (int i = 0; i < 20; i++) {
        cout << "y[" << i + 1 << "] = " << mas[i];
        if (i < 19) cout << ", ";
        else cout << endl;
    }
    ENDL;

    cout << "Среди всех значений массива маске (01010100) соответствуют следующие значения:" << endl;
    cout << "------------------------------------------------------------------------------" << endl;

    bool found = false;
    for (int i = 0; i < 20; i++) {
        if ((mas[i] & maska) == maska) {
            cout << "y[" << i + 1 << "] = " << mas[i]
                 << " (dec), 0x" << hex << mas[i] << dec << " (hex), ob"
                 << bitset<sizeof(mas[i]) * 8>(mas[i]) << " (bin)" << endl;
            found = true;
        }
    }

    if (!found) {
        cout << "Нет чисел, соответствующих маске 01010100 (0x54)" << endl;
    }

    ENDL;
    system("pause");
    return 0;
}

// ========== МАКРОСЫ (ИСПРАВЛЕН - использует int temp) ==========
int Macros() {
    system("cls");
    info();

    cout << "===========================================================\n";
    cout << "Макросы Hi, Lo, Swap\n";
    cout << "===========================================================\n\n";

    unsigned char B = 0;
    unsigned short Sh = 0;
    unsigned int I = 0;
    unsigned long long LL = 0;
    int temp = 0;