Что это?

Тестовое задание для участия в мероприятии “Ночь в финтехе“:

Привет! Чтобы попасть на Ночь в Финтехе, осталось всего ничего — решить контест. Так мы поймём, что ты точно бекэнд-разработчик, а не очень любопытный маркетолог, например 😉

У тебя будет 3 часа и 4 задачи. Начать можно в любой момент — так что успеешь найти тихое место, сделать чай и приготовить что-нибудь пожевать. При регистрации обязательно укажи почту, на которую пришло это письмо.

Не страшно, если не успеешь решить всё — главное прогресс. И это точно не последняя наша вечеринка. В любом случае, напиши боту https://t.me/fintech_night_bot, чтобы следить за этой Ночью в Финтехе и следующими.

Удачи 🍀

(warning) Будем решать его с помощью нейронной сети ChatGPT с авто-генерацией кода по заданному словесному описанию.


Задача

Задача A. Cамокаты

Ограничение времени: 1 секунда

Ограничение памяти: 256Mb

Ввод: стандартный ввод или input.txt

Вывод: стандартный вывод или output.txt

Наш пользователь Федя обожает самокаты и мосты, и неплохо совмещает одно с другим. В этом году он решил отправиться в самое долгое двухколёсное путешествие к самому длинному вантовому мосту в мире — на остров Русский. Оплатить поездку «Москва – Владивосток – Москва» он, конечно, решил Картой Плюса. Но сумма вышла настолько космической, что сломался код.

Помоги нашему сеньору Боре посчитать, какой минимум должен лежать у Феди на счету, чтобы он, как Фродо, смог доехать туда и обратно.

Число представлено в виде массива — внутри квадратных скобок все цифры этого числа, перечисленные через запятую. Например, 12 (двенадцать) — это строка «[1, 2]».

Формат ввода

Две строки, каждая из которых представляет собой число.

Формат вывода

Одна строка, представляющая собой число.

Пример

Ввод

[1, 2] [2, 5]

Вывод

[3, 7]

Решаем

Складываем два вектора

(звезда) Просим нейронку ChatGPT нам помочь: пишем запрос:

Напиши программу на C++ для сложения элементов из двух массивов с целыми числами.

Получаем ответ:

#include <iostream>

void sumArrays(int array1[], int array2[], int size) {
    int result[size];

    // Сложение элементов двух массивов
    for (int i = 0; i < size; i++) {
        result[i] = array1[i] + array2[i];
    }

    // Вывод результата
    std::cout << "Сумма элементов массивов: ";
    for (int i = 0; i < size; i++) {
        std::cout << result[i] << " ";
    }
    std::cout << std::endl;
}

int main() {
    const int size = 5;
    int array1[size] = {1, 2, 3, 4, 5};
    int array2[size] = {6, 7, 8, 9, 10};

    sumArrays(array1, array2, size);

    return 0;
}

Складываем два вектора из файла

… но нам нужно читать данные из файла и выводить в файл; ок, перепишем запрос:

Напиши программу на C++ для сложения элементов из двух массивов с целыми числами. Массивы хранятся в файле input.txt , результат надо вывести в файл output.txt

#include <iostream>
#include <fstream>
#include <vector>

void sumArrays(const std::vector<int>& array1, const std::vector<int>& array2, std::ofstream& outputFile) {
    std::vector<int> result;

    // Проверка на равенство размеров массивов
    if (array1.size() != array2.size()) {
        outputFile << "Ошибка: размеры массивов не совпадают." << std::endl;
        return;
    }

    // Сложение элементов двух массивов
    for (size_t i = 0; i < array1.size(); i++) {
        result.push_back(array1[i] + array2[i]);
    }

    // Запись результата в файл
    for (const auto& num : result) {
        outputFile << num << " ";
    }
    outputFile << std::endl;
}

int main() {
    std::ifstream inputFile("input.txt");
    std::ofstream outputFile("output.txt");

    if (!inputFile) {
        std::cout << "Ошибка: невозможно открыть файл 'input.txt'." << std::endl;
        return 1;
    }

    if (!outputFile) {
        std::cout << "Ошибка: невозможно открыть файл 'output.txt'." << std::endl;
        return 1;
    }

    std::vector<int> array1, array2;
    int num;

    // Чтение массива 1 из файла
    while (inputFile >> num) {
        array1.push_back(num);
    }

    // Проверка на конец файла или ошибку чтения
    if (!inputFile.eof() && !inputFile.good()) {
        std::cout << "Ошибка: ошибка чтения из файла 'input.txt'." << std::endl;
        return 1;
    }

    // Переоткрытие файла для чтения массива 2
    inputFile.clear();
    inputFile.seekg(0, std::ios::beg);

    // Чтение массива 2 из файла
    while (inputFile >> num) {
        array2.push_back(num);
    }

    // Проверка на конец файла или ошибку чтения
    if (!inputFile.eof() && !inputFile.good()) {
        std::cout << "Ошибка: ошибка чтения из файла 'input.txt'." << std::endl;
        return 1;
    }

    // Сложение массивов и запись результата в файл
    sumArrays(array1, array2, outputFile);

    std::cout << "Результат успешно записан в файл 'output.txt'." << std::endl;

    inputFile.close();
    outputFile.close();

    return 0;
}

Пояснение нейронки:

В этом примере мы используем классы ifstream и ofstream из заголовочного файла <fstream> для работы с файлами. В функции main мы открываем файлы «input.txt» и «output.txt» для чтения и записи соответственно.

Затем мы считываем элементы из файла «input.txt» в два вектора array1 и array2. После этого вызываем функцию sumArrays, которая складывает элементы массивов.

(минус) Проблема:

тут нейронка ждет на вход данные в формате:

1 2
2 5

а нам нужно:

[1, 2]
[2, 5]

Чтение данных из файла в нужном формате

(warning) Просим нейронку написать функцию для чтения массивов в указанном формате:

Напиши программу на C++ для чтения массива из файла input.txt , пример массива: [1, 2, 3]

#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>

std::vector<int> readArrayFromFile(const std::string& filename) {
    std::ifstream inputFile(filename);
    std::vector<int> array;

    if (!inputFile) {
        std::cout << "Ошибка: невозможно открыть файл " << filename << std::endl;
        return array;
    }

    std::string line;
    std::getline(inputFile, line);

    // Удаление символов '[' и ']' из строки
    line.erase(std::remove(line.begin(), line.end(), '['), line.end());
    line.erase(std::remove(line.begin(), line.end(), ']'), line.end());

    // Разделение строки на элементы массива
    std::stringstream ss(line);
    std::string item;
    while (std::getline(ss, item, ',')) {
        // Преобразование элемента в целое число
        int num = std::stoi(item);
        array.push_back(num);
    }

    inputFile.close();

    return array;
}

int main() {
    std::vector<int> array = readArrayFromFile("input.txt");

    std::cout << "Массив из файла: ";
    for (const auto& num : array) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

Пояснение нейронки:

В этом примере мы используем класс ifstream из заголовочного файла <fstream> для открытия и чтения файла «input.txt». Функция readArrayFromFile принимает имя файла в качестве аргумента и возвращает вектор считанных элементов.

Мы считываем строку из файла и удаляем символы ‘[‘ и ‘]’ с помощью функций erase и remove. Затем мы используем std::stringstream для разделения строки на отдельные элементы, разделенные запятыми. Каждый элемент преобразуется в целое число с помощью std::stoi и добавляется в вектор array.

В функции main вызываем функцию readArrayFromFile для чтения массива из файла «input.txt». Затем выводим элементы массива на экран.

Объединим запросы

Лень объединять два решения выше в одно, попросим нейронку это сделать грамотным query:

Напиши программу на C++ для сложения элементов из двух массивов с целыми числами.

Массивы хранятся в файле input.txt , например:

[1, 2, 3]

[4, 5, 6]

результат надо вывести в файл output.txt, например:

[5, 7, 9]
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>

std::vector<int> readArrayFromFile(const std::string& filename) {
    std::ifstream inputFile(filename);
    std::vector<int> array;

    if (!inputFile) {
        std::cout << "Ошибка: невозможно открыть файл " << filename << std::endl;
        return array;
    }

    std::string line;
    std::getline(inputFile, line);

    // Удаление символов '[' и ']' из строки
    line.erase(std::remove(line.begin(), line.end(), '['), line.end());

    // Разделение строки на элементы массива
    std::stringstream ss(line);
    std::string item;
    while (std::getline(ss, item, ',')) {
        // Преобразование элемента в целое число
        int num = std::stoi(item);
        array.push_back(num);
    }

    inputFile.close();

    return array;
}

void sumArrays(const std::vector<int>& array1, const std::vector<int>& array2, std::ofstream& outputFile) {
    std::vector<int> result;

    // Проверка на равенство размеров массивов
    if (array1.size() != array2.size()) {
        outputFile << "Ошибка: размеры массивов не совпадают." << std::endl;
        return;
    }

    // Сложение элементов двух массивов
    for (size_t i = 0; i < array1.size(); i++) {
        result.push_back(array1[i] + array2[i]);
    }

    // Запись результата в файл
    outputFile << "[";
    for (size_t i = 0; i < result.size(); i++) {
        outputFile << result[i];
        if (i != result.size() - 1) {
            outputFile << ", ";
        }
    }
    outputFile << "]" << std::endl;
}

int main() {
    std::vector<int> array1 = readArrayFromFile("input.txt");
    std::vector<int> array2 = readArrayFromFile("input.txt");

    std::ofstream outputFile("output.txt");

    if (!outputFile) {
        std::cout << "Ошибка: невозможно открыть файл 'output.txt'." << std::endl;
        return 1;
    }

    // Сложение массивов и запись результата в файл
    sumArrays(array1, array2, outputFile);

    std::cout << "Результат успешно записан в файл 'output.txt'." << std::endl;

    outputFile.close();

    return 0;
}

Пояснение нейронки:

В этом примере мы снова используем функцию readArrayFromFile для считывания массивов из файла «input.txt» и сохранения их в вектора array1 и array2.

Затем мы создаем функцию sumArrays, которая принимает два массива и файловый поток для записи результата. Функция проверяет, что размеры массивов совпадают, затем складывает элементы массивов и записывает результат

Тут некорректно работает строчка по обрезанию скобок []:

line.erase(std::remove(line.begin(), line.end(), '['), line.end());

Поправим ее на другую:

Напиши программу на C++ для удаление первого и последнего символа в строке

#include <iostream>
#include <string>

std::string removeFirstAndLastChar(const std::string& str) {
    if (str.length() <= 2) {
        // Если строка содержит менее или равно 2 символам, возвращаем пустую строку
        return "";
    }
    
    // Извлечение подстроки без первого и последнего символа
    return str.substr(1, str.length() - 2);
}

int main() {
    std::string input;
    std::cout << "Введите строку: ";
    std::getline(std::cin, input);
    
    std::string result = removeFirstAndLastChar(input);
    
    std::cout << "Результат: " << result << std::endl;
    
    return 0;
}

Собираем итоговое решение (уже сами)

#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>

std::string removeFirstAndLastChar(const std::string& str) {
    if (str.length() <= 2) {
        // Если строка содержит менее или равно 2 символам, возвращаем пустую строку
        return "";
    }
    
    // Извлечение подстроки без первого и последнего символа
    return str.substr(1, str.length() - 2);
}

std::vector<int> readArrayFromFile(const std::string& filename, int lineNum) {
    std::ifstream inputFile(filename);
    std::vector<int> array;

    if (!inputFile) {
        std::cout << "Ошибка: невозможно открыть файл " << filename << std::endl;
        return array;
    }

    std::string line;
    
    int curLine = 0;
    while(curLine != lineNum) {
        std::getline(inputFile, line);
        curLine++;
    }
    
    std::getline(inputFile, line);

    // Удаление символов '[' и ']' из строки
    line = removeFirstAndLastChar(line);    
    
    //std::cout << line << "n";

    // Разделение строки на элементы массива
    std::stringstream ss(line);
    std::string item;
    
    while (std::getline(ss, item, ',')) {
        // Преобразование элемента в целое число
        int num = std::stoi(item);
        array.push_back(num);
        
        //std::cout << num << "n";
    }

    inputFile.close();

    return array;
}

void sumArrays(const std::vector<int>& array1, const std::vector<int>& array2, std::ofstream& outputFile) {
    std::vector<int> result;

    // Проверка на равенство размеров массивов
    if (array1.size() != array2.size()) {
        outputFile << "Ошибка: размеры массивов не совпадают." << std::endl;
        return;
    }

    // Сложение элементов двух массивов
    for (size_t i = 0; i < array1.size(); i++) {
        result.push_back(array1[i] + array2[i]);
    }

    // Запись результата в файл
    outputFile << "[";
    for (size_t i = 0; i < result.size(); i++) {
        outputFile << result[i];
        
        //std::cout << result[i] << "n";
        
        if (i != result.size() - 1) {
            outputFile << ", ";
        }
    }
    outputFile << "]" << std::endl;
}

int main() {
    std::vector<int> array1 = readArrayFromFile("input.txt", 0);
    std::vector<int> array2 = readArrayFromFile("input.txt", 1);

    std::ofstream outputFile("output.txt");

    if (!outputFile) {
        std::cout << "Ошибка: невозможно открыть файл 'output.txt'." << std::endl;
        return 1;
    }

    // Сложение массивов и запись результата в файл
    sumArrays(array1, array2, outputFile);

    //std::cout << "Результат успешно записан в файл 'output.txt'." << std::endl;

    outputFile.close();

    return 0;
}

Проверяем/запускаем код

(warning) Ищем любой онлайн-компилятор, например: https://www.online-cpp.com/

Вставляем наше решение, запускаем: (все работает)

Отсылаем на проверку Яндексу:

(минус) Третий тест не пройден, вот почему: нужно учитывать переполнение разрядов, пример:

[9,9]
[7,8]
==>
[16,17]

А должно быть: 
[1,7,7]

переписываем ф-ю sumArrays:

// функция для реверса массива чецлых чисел
void reverseArray(std::vector<int>& array) {
    int start = 0;
    int end = array.size() - 1;

    while (start < end) {
        // Обмен элементов start и end
        int temp = array[start];
        array[start] = array[end];
        array[end] = temp;

        start++;
        end--;
    }
}

void sumArrays(const std::vector<int>& array1, const std::vector<int>& array2, std::ofstream& outputFile) {
    std::vector<int> result;

    // Проверка на равенство размеров массивов
    if (array1.size() != array2.size()) {
        outputFile << "Ошибка: размеры массивов не совпадают." << std::endl;
        return;
    }

    // Сложение элементов двух массивов
    // (*) побайтовое, начиная с конца
    int res, ost = 0;
    for (int i = array1.size() - 1; i >= 0 ; i--) {
        res = (array1[i] + array2[i] + ost);
        if(res > 9) {
            res -= 10;
            ost = 1;
        } else {
            ost = 0;
        }
        result.push_back(res);
    }

    if(ost > 0) {
        result.push_back(ost);
    }
    reverseArray(result);

    // Запись результата в файл
    outputFile << "[";
    for (size_t i = 0; i < result.size(); i++) {
        outputFile << result[i];
        
        std::cout << result[i] << "n";
        
        if (i != result.size() - 1) {
            outputFile << ", ";
        }
    }
    outputFile << "]" << std::endl;
}

Проверяем на своем тесте:

[9,1,9]
[7,1,3]
==>
[1,6,3,2]

Проверяем на компиляторе Яндекса

(минус) опять ошибка (но не показывает, на каких данных , зараза….)

(warning) Полагаю, что массивы 1 и 2 из input.txt могут быть разной длины…. Что ж, учтем это:

Проверяем:

    [9,1,9]
[4,5,7,1,3]
==>
[4,6,6,3,2]

Снова просим нейронку помочь

Напиши программу на C++ для сложения двух чисел, представленных в виде строк.

Вот что имеем:

#include <iostream>
#include <string>

std::string addStrings(const std::string& num1, const std::string& num2) {
    std::string result;
    int carry = 0;
    int i = num1.length() - 1;
    int j = num2.length() - 1;

    while (i >= 0 || j >= 0 || carry > 0) {
        int digit1 = (i >= 0) ? (num1[i] - '0') : 0;
        int digit2 = (j >= 0) ? (num2[j] - '0') : 0;

        int sum = digit1 + digit2 + carry;
        carry = sum / 10;
        int digit = sum % 10;

        result = std::to_string(digit) + result;

        i--;
        j--;
    }

    return result;
}

int main() {
    std::string num1 = "123";
    std::string num2 = "456";

    std::string sum = addStrings(num1, num2);

    std::cout << "Сумма: " << sum << std::endl;

    return 0;
}

Комментарий:

В этом примере мы определяем функцию addStrings, которая принимает две строки num1 и num2 в качестве параметров. Мы используем алгоритм сложения «столбиком», начиная с младших разрядов чисел. Мы также используем переменную carry для хранения переноса при сложении разрядов.

В цикле while мы проходим по обеим строкам num1 и num2, начиная с младших разрядов, и выполняем сложение цифр, перенос и формирование результата.

В функции main мы задаем две строки num1 и num2, представляющие числа, которые мы хотим сложить. Затем вызываем функцию addStrings для сложения чисел и сохранения результата в строке sum. Наконец, выводим полученную сумму на экран.

Позаимствуем тут логику для метода sumArrays:

// Сложение элементов двух массивов
// (*) побайтовое, начиная с конца
std::vector<int> sumArrays(const std::vector<int>& array1, const std::vector<int>& array2) 
{
    std::vector<int> result;

    int carry = 0;
    int i = array1.size() - 1;
    int j = array2.size() - 1;

    while (i >= 0 || j >= 0 || carry > 0) {
        int digit1 = (i >= 0) ? array1[i] : 0;
        int digit2 = (j >= 0) ? array2[j] : 0;

        int sum = digit1 + digit2 + carry;
        carry = sum / 10;
        int digit = sum % 10;

        result.push_back(digit);

        i--;
        j--;
    }
    
    reverseArray(result);

    return result;
}

Скармливаем на проверку Яндексу:

(warning) Ура, принято, пройдено около 40 тестов успешно, с 7й попытки!

Итого, наше финальное решение:

Финальное решение (рабочее)

#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <list>

std::string removeFirstAndLastChar(const std::string& str) {
    if (str.length() <= 2) {
        // Если строка содержит менее или равно 2 символам, возвращаем пустую строку
        return "";
    }
    
    // Извлечение подстроки без первого и последнего символа
    return str.substr(1, str.length() - 2);
}

// функция для реверса массива чецлых чисел
void reverseArray(std::vector<int>& array) {
    int start = 0;
    int end = array.size() - 1;

    while (start < end) {
        // Обмен элементов start и end
        int temp = array[start];
        array[start] = array[end];
        array[end] = temp;

        start++;
        end--;
    }
}

std::vector<int> readArrayFromFile(const std::string& filename, int lineNum) {
    std::ifstream inputFile(filename);
    std::vector<int> array;

    if (!inputFile) {
        std::cout << "Ошибка: невозможно открыть файл " << filename << std::endl;
        return array;
    }

    std::string line;
    
    int curLine = 0;
    while(curLine != lineNum) {
        std::getline(inputFile, line);
        curLine++;
    }
    
    std::getline(inputFile, line);

    // Удаление символов '[' и ']' из строки
    line = removeFirstAndLastChar(line);    
    
    // Разделение строки на элементы массива
    std::stringstream ss(line);
    std::string item;
    
    while (std::getline(ss, item, ',')) {
        // Преобразование элемента в целое число
        int num = std::stoi(item);
        array.push_back(num);
    }

    inputFile.close();

    return array;
}

// Сложение элементов двух массивов
// (*) побайтовое, начиная с конца
std::vector<int> sumArrays(const std::vector<int>& array1, const std::vector<int>& array2) 
{
    std::vector<int> result;

    int carry = 0;
    int i = array1.size() - 1;
    int j = array2.size() - 1;

    while (i >= 0 || j >= 0 || carry > 0) {
        int digit1 = (i >= 0) ? array1[i] : 0;
        int digit2 = (j >= 0) ? array2[j] : 0;

        int sum = digit1 + digit2 + carry;
        carry = sum / 10;
        int digit = sum % 10;

        result.push_back(digit);

        i--;
        j--;
    }
    
    reverseArray(result);

    return result;
}

void printArray(const std::vector<int>& result, std::ofstream& outputFile)
{
    // Запись результата в файл
    outputFile << "[";
    
    for (size_t i = 0; i < result.size(); i++) {
        outputFile << result[i];
        
        if (i != result.size() - 1) {
            outputFile << ", ";
        }
    }
    
    outputFile << "]" << std::endl;    
    
    return;
}

int main() {
    std::vector<int> array1 = readArrayFromFile("input.txt", 0);
    std::vector<int> array2 = readArrayFromFile("input.txt", 1);

    std::ofstream outputFile("output.txt");

    if (!outputFile) {
        std::cout << "Ошибка: невозможно открыть файл 'output.txt'." << std::endl;
        return 1;
    }

    // Сложение массивов и запись результата в файл
    std::vector<int> result = sumArrays(array1, array2);
    
    printArray(result, outputFile);

    outputFile.close();

    return 0;
}

Пример ввода-вывода:

input.txt

[9,1,9]
[4,5,7,1,3]

output.txt

[4,6,6,3,2]

PS: читайте мои другие заметки о работе с ChatGPT в моем блоге и телеграм

Tags

Нет Ответов

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Рубрики


Подпишись на новости
👋

Есть вопросы?