#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#define MAX_LENGTH 256

void read_input(char *input, size_t size) {
    if (fgets(input, size, stdin) == NULL) {
        fprintf(stderr, "Error reading input.\n");
        exit(1); 
    }
    input[strcspn(input, "\n")] = '\0';  
}

void invertSymmetry(char *result) {
    while (*result) {
        *result = (*result == '1') ? 'i' : (*result == 'i' ? '1' : *result);
        ++result;
    }
}

// Функция для создания фиксированной матрицы 2 на 256
char* thirdFunction(char matrix[2][MAX_LENGTH], int rows) {
    static char result[MAX_LENGTH];  // Статический массив для возвращаемой строки
    memset(result, '0', MAX_LENGTH); // Инициализация нулями

    printf("Высота: %d\n", rows);
    int columns = strlen(matrix[0]);
    printf("Длина: %d\n", columns);

    printf("\nПолученная матрица:\n");
    for (int i = 0; i < rows; i++) {
        printf("%s\n", matrix[i]);
    }

    int x, z, r, y = 0, g;
    char current_result[columns + 1];  
    current_result[0] = '\0';           

    int j = columns - 1;  
    while (j >= 0 || y != 0) {
        x = 0; g = 0; r = 0;  

        int skip = 0;

        for (int i = 0; i < rows; i++) {
            char n = (j >= 0) ? matrix[i][j] : '0';    
            if (n == '1') {
                x += 1;
            } else if (n == 'i') {
                x -= 1;
            } else if (n == ',' || n == '.') {
                memmove(current_result + 1, current_result, strlen(current_result) + 1);
                current_result[0] = ',';  
                skip = 1;
                break;  
            }
        }

        if (skip) {
            j--;  
            continue;
        }
        x += y;  
        r = (x < 0) ? -1 : 1;
        z = abs(x) % 3;  
        if (z == 2) {
            z = -1;
            g = 1;
        }
        z *= r;
        g *= r;
        memmove(current_result + 1, current_result, strlen(current_result) + 1);

        if (z == -1) {
            current_result[0] = 'i';
        } else if (z == 1) {
            current_result[0] = '1';
        } else if (z == 0) {
            current_result[0] = '0';
        }
        y = x / 3;
        y = y * r;
        y += g;

        if (j >= 0) {
            j--;
        }
    }

    // Удаление ведущих '0' с изменением самого массива
    /*char *first_nonzero = current_result;
    while (*first_nonzero == '0') {
        first_nonzero++;
    }*/

    // Если вся строка была из '0', оставляем один '0'
    /*if (*first_nonzero == '\0') {
        first_nonzero--;  // Вернемся на последний '0'
    }*/

    // Перезаписываем массив с найденного элемента
    /*size_t new_length = strlen(first_nonzero) + 1; // +1 для '\0'
    memmove(current_result, first_nonzero, new_length);*/

    //printf("Resulting string: %s\n", current_result);
    
    // Копируем результат в result, чтобы передать его в основную функцию
    strncpy(result, current_result, MAX_LENGTH - 1);
    result[MAX_LENGTH - 1] = '\0';  // Обеспечиваем завершающий ноль

    return result;
}



// Функция для выполнения основной логики
void newFunction(char input1[], char input2[]) {
    int n1 = strlen(input1);
    int n2 = strlen(input2);

    // Найти позиции запятой или точки
    char* comma1_pos = strpbrk(input1, ",.");
    char* comma2_pos = strpbrk(input2, ",.");

    if (comma1_pos) {
        n1 = comma1_pos - input1;  // Индекс до запятой
    }

    if (comma2_pos) {
        n2 = comma2_pos - input2;  // Индекс до запятой
    }

    int a1 = strlen(input1);
    int a2 = strlen(input2);

    // Добавляем разницу в длине до запятой
    if (n1 < n2) {
        a1 += (n2 - n1);
    }

    if (n2 < n1) {
        a2 += (n1 - n2);
    }

    // Берем максимальную длину строк
    int max_a = (a1 > a2) ? a1 : a2;
    int n = 2;  

    char matrix[2][MAX_LENGTH];
    memset(matrix, '0', sizeof(matrix));  // Заполняем нулями
    matrix[0][max_a] = '\0';  // Добавляем нуль-терминатор
    matrix[1][max_a] = '\0';

    int start_idx1 = (n1 < n2) ? n2 - n1 : 0;
    memcpy(matrix[0] + start_idx1, input1, strlen(input1)); 

    int start_idx2 = (n2 < n1) ? n1 - n2 : 0;
    memcpy(matrix[1] + start_idx2, input2, strlen(input2));

    // Получаем результат из thirdFunction
    char* result = thirdFunction(matrix, n);
    printf("\nРезультат третьей функции: %s\n", result);
}



void newAdd(char input1[], char input2[]) {
    char temp[MAX_LENGTH];
    // Найти позиции запятых или точек
    char* comma1_pos = strpbrk(input1, ",.");
    char* comma2_pos = strpbrk(input2, ",.");

    int len1 = strlen(input1);
    int len2 = strlen(input2);
    
    int index1 = comma1_pos ? (int)(comma1_pos - input1) + 1 : len1;
    int index2 = comma2_pos ? (int)(comma2_pos - input2) + 1 : len2;
    
    int n = (len1 - index1) + (len2 - index2);
    
    // Функция для удаления первого вхождения '.' или ','
    void removeChar(char* str) {
        char* pos = strpbrk(str, ",.");
        if (pos) {
            memmove(pos, pos + 1, strlen(pos)); // Сдвиг влево
        }
    }
    
    removeChar(input1);
    removeChar(input2);
    
    // Сохраняем длины строк после удаления
    len1 = strlen(input1);
    len2 = strlen(input2);
    
    // Проверяем длины и меняем местами, если вторая строка длиннее
    if (len2 > len1) {
        strcpy(temp, input2);
        strcpy(input2, input1);
        strcpy(input1, temp);
        int templen = len2;
        len2 = len1;
        len1 = templen;
    } else {
        strcpy(temp, input1);
    }
    // Инвертируем строку temp (предположим, что invertSymmetry это функция инверсии)
    invertSymmetry(temp);
    
    // Вычисляем len как разницу длин строк
    char matrix[len2][MAX_LENGTH];
    memset(matrix, '0', sizeof(matrix));  // Инициализируем весь массив нулями (пустыми символами)


    int len=len1-len2;
int s = len2 - 1; // Начнем с нижней строки и будем уменьшать s
for (int i = 0; i < len2; i++) {
    if (input2[i] == '1') {
        // Копируем строку input1 в matrix[s], с учетом уменьшения отступа
        memcpy(matrix[s] + (len2 - 1 - s), input1, MAX_LENGTH - (len2 - 1 - s));
    }
    else if (input2[i] == 'i') {
        // Копируем строку temp в matrix[s], с учетом уменьшения отступа
        memcpy(matrix[s] + (len2 - 1 - s), temp, MAX_LENGTH - (len2 - 1 - s));
    }
    else if (input2[i] == '0') { matrix[s][len1+len2-1] = '\0';}
    // Уменьшаем s, двигаясь вверх по матрице
    s--;
}
/*
    // Выводим результат
    for (int i = 0; i < len2; i++) {
        // Добавляем символы '/' для пустых мест
        for (int j = 0; j < len; j++) {
            if (matrix[i][j] == '\0') {
                //matrix[i][j] = ' ';  // Заполняем пустые места
            }
        }
        printf("matrix[%d]: %s\n", i, matrix[i]);
    }

    
    // Вывод результатов
    /*printf("Значение n: %d\n", n);
    printf("Первая строка после удаления: %s\n", input1);
    printf("Вторая строка после удаления: %s\n", input2);
    printf("Первая строка после инверсии: %s\n", temp);
    printf("Длина первой строки после удаления: %d\n", len1);
    printf("Длина второй строки после удаления: %d\n", len2);*/
    
    char* result = thirdFunction(matrix, len2);
    n=strlen(result)-n;
    if (n>0 && n!=(len1+len2)){
    memmove(result + n + 1, result + n, strlen(result) - n + 1);
    result[n] = ',';}
    printf("\nРезультат третьей функции: %s\n", result);
    
}


/*
void binary_and() {
    char input1[100];
    char input2[100];
    int matrix[2][MAX_LENGTH];
    printf("\nEnter the first ternary symmetric number: ");
    read_input(input1, MAX_LENGTH);
    printf("Enter the second ternary symmetric number: ");
    read_input(input2, MAX_LENGTH);

    ArrayResult result = CreateAnArray(input1, input2, matrix);

    int columns = result.column;  
    int wq = result.row;          

    char final_result[MAX_LENGTH] = {0};
    int result_index = 0;

    printf("\nColumns: %d\n", columns);
    printf("wq: %d\n", wq); 

    for (int j = 0; j < columns; j++) {
        if (matrix[0][j] == 'i' || matrix[1][j] == 'i') {
            final_result[result_index++] = 'i';
        } else if (matrix[0][j] == '0' || matrix[1][j] == '0') {
            final_result[result_index++] = '0';
        } else if (matrix[0][j] == '1' && matrix[1][j] == '1') {
            final_result[result_index++] = '1';
        } else if (matrix[0][j] == ',' || matrix[0][j] == '.' || matrix[1][j] == ',' || matrix[1][j] == '.') {
            final_result[result_index++] = ',';
        } else {
            final_result[result_index++] = '0';
        }
    }
    final_result[result_index] = '\0';
    printf("\nResulting string: %s\n", final_result);
}

void binary_or() {
    char input1[100];
    char input2[100];
    int matrix[2][MAX_LENGTH];
    printf("\nEnter the first ternary symmetric number: ");
    read_input(input1, MAX_LENGTH);
    printf("Enter the second ternary symmetric number: ");
    read_input(input2, MAX_LENGTH);

    ArrayResult result = CreateAnArray(input1, input2, matrix);

    int columns = result.column;  
    int wq = result.row;         

    char final_result[MAX_LENGTH] = {0};
    int result_index = 0;

    printf("\nColumns: %d\n", columns);
    printf("wq: %d\n", wq);  

    printf("\nResulting matrix:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < columns; j++) {
            printf("%c ", matrix[i][j]);
        }
        printf("\n");
    }

    for (int j = 0; j < columns; j++) {
        if (matrix[0][j] == '1' || matrix[1][j] == '1') {
            final_result[result_index++] = '1';  
        } else if (matrix[0][j] == '0' || matrix[1][j] == '0') {
            final_result[result_index++] = '0'; 
        } else if (matrix[0][j] == 'i' && matrix[1][j] == 'i') {
            final_result[result_index++] = 'i';  
        } else if (matrix[0][j] == ',' || matrix[0][j] == '.' || matrix[1][j] == ',' || matrix[1][j] == '.') {
            final_result[result_index++] = ',';  
        } else {
            final_result[result_index++] = '0';
        }
    }
    final_result[result_index] = '\0';
    printf("\nResulting string: %s\n", final_result);
}
*/

void threeToTen() {
    char input[256];

    printf("\nEnter a string: ");
    read_input(input, MAX_LENGTH);

    char *delimiter = strpbrk(input, ".,");
    int n = (delimiter) ? (delimiter - input - 1) : (strlen(input) - 1);
    
    double result = 0;

    for (int i = 0; input[i] != '\0'; i++) {
        if (input[i] == '.' || input[i] == ',') {
            continue;
        } else if (input[i] == 'i') {
            result += -1 * pow(3, n);
        } else if (isdigit(input[i])) {
            result += (input[i] - '0') * pow(3, n);
        }
        n--;
    }
    printf("Decimal value: %.10f\n", result);
}

void symmetry(const char *input, int isNegative) {
    printf("Non-symmetrical result: %s\n", input);
    size_t len = strlen(input);
    char result[MAX_LENGTH] = "";
    int x = 0, y = 0, z = 0;

    for (int i = len - 1; i >= 0; i--) {
        if (input[i] == ',') {
            memmove(result + 1, result, strlen(result) + 1);
            result[0] = ',';
            continue;
        }

        x = input[i] - '0'; 
        z = y + x;

        if (z <= 1) {
            memmove(result + 1, result, strlen(result) + 1);
            result[0] = z + '0';
            y = 0;
        } else if (z == 2) {
            memmove(result + 1, result, strlen(result) + 1);
            result[0] = 'i';
            y = 1;
        } else if (z == 3) {
            memmove(result + 1, result, strlen(result) + 1);
            result[0] = '0';
            y = 1;
        }
    }

    if (y != 0) {
        memmove(result + 1, result, strlen(result) + 1);
        result[0] = y + '0';
    }

    if (isNegative) {
        invertSymmetry(result);
    }

    printf("Symmetrical result: %s\n", result);
}

void whole_part(char *part) {
    long long number = strtoll(part, NULL, 10);

    if (number == 0) {
        part[0] = '0';
        part[1] = '\0';
    } else {
        char buffer[2];
        part[0] = '\0'; 

        while (number > 0) {
            sprintf(buffer, "%d", number % 3);
            memmove(part + 1, part, strlen(part) + 1);
            part[0] = buffer[0]; 
            number /= 3;
        }
    }
}

void fraction_part(char *part) {
    double fractionalValue = atof(part) / pow(10, strlen(part));
    char buffer[2];
    part[0] = '\0'; 

    for (int i = 0; i < 15; i++) {
        fractionalValue *= 3;
        int digit = (int)fractionalValue;
        fractionalValue -= digit;
        sprintf(buffer, "%d", digit);
        strcat(part, buffer); 
    }
}

void translation() {
    char input[256];
    char firstPart[128] = "";
    char secondPart[128] = "";
    int isNegative = 0;

    printf("\nEnter a string: ");
    read_input(input, MAX_LENGTH);

    if (strchr(input, '-') != NULL) {
        isNegative = 1;
        memmove(input, input + 1, strlen(input)); 
    }

    char *delimiter = strpbrk(input, ".,");

    if (delimiter) {
        size_t firstLen = delimiter - input;
        strncpy(firstPart, input, firstLen);
        firstPart[firstLen] = '\0';

        strcpy(secondPart, delimiter + 1);
    } else {
        strcpy(firstPart, input);
    }

    whole_part(firstPart);
    if (strlen(secondPart) > 0) {
        fraction_part(secondPart);
    } else {
        strcpy(secondPart, "0"); 
    }

    char combined[MAX_LENGTH] = "";
    snprintf(combined, sizeof(combined), "%s,%s", firstPart, secondPart);

    symmetry(combined, isNegative);
}

int main() {
    int choice;
    char input1[MAX_LENGTH], input2[MAX_LENGTH];
    int n;  // Размер матрицы

    int matrix[MAX_LENGTH][MAX_LENGTH];  // Матрица произвольного размера

    do {
        printf("\nМеню:\n");
        printf("1. From Ternary\n");
        printf("2. From Decimal\n");
        printf("3.  сложения\n");
        printf("4.  вычитание\n");
        printf("5.  умножение\n");
        printf("0. Выход\n");
        printf("Введите ваш выбор: ");

        if (scanf("%d", &choice) != 1) {
            fprintf(stderr, "Неверный ввод. Выход.\n");
            break;
        }

        while (getchar() != '\n'); // Ожидаем ввода

        switch (choice) {
            case 1:
                translation();
                break;
            case 2:
                threeToTen();
                break;
            case 3:
    printf("Введите первую строку: ");
    read_input(input1, MAX_LENGTH);  
    printf("Введите вторую строку: ");
    read_input(input2, MAX_LENGTH);  
    newFunction(input1, input2); 
                break;
            case 4:
    printf("Введите первую строку: ");
    read_input(input1, MAX_LENGTH);  
    printf("Введите вторую строку: ");
    read_input(input2, MAX_LENGTH);
    invertSymmetry(input2);
    newFunction(input1, input2); 
                break;
            case 5:
    printf("Введите первую строку: ");
    read_input(input1, MAX_LENGTH);  
    printf("Введите вторую строку: ");
    read_input(input2, MAX_LENGTH);  
    newAdd(input1, input2);  
                break;
            case 0:
                printf("Выход из программы.\n");
                break;
            default:
                printf("Неверный выбор. Попробуйте снова.\n");
        }
    } while (choice != 0);

    return 0;
}
