Что это?
Тестовое задание для участия в мероприятии “Ночь в финтехе“:
Привет! Чтобы попасть на Ночь в Финтехе, осталось всего ничего — решить контест. Так мы поймём, что ты точно бекэнд-разработчик, а не очень любопытный маркетолог, например
У тебя будет 3 часа и 4 задачи. Начать можно в любой момент — так что успеешь найти тихое место, сделать чай и приготовить что-нибудь пожевать. При регистрации обязательно укажи почту, на которую пришло это письмо.
Не страшно, если не успеешь решить всё — главное прогресс. И это точно не последняя наша вечеринка. В любом случае, напиши боту https://t.me/fintech_night_bot, чтобы следить за этой Ночью в Финтехе и следующими.
Удачи
Будем решать его с помощью нейронной сети 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]
Чтение данных из файла в нужном формате
Просим нейронку написать функцию для чтения массивов в указанном формате:
Напиши программу на 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; }
Проверяем/запускаем код
Ищем любой онлайн-компилятор, например: 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]
Проверяем на компиляторе Яндекса…
опять ошибка (но не показывает, на каких данных , зараза….)
Полагаю, что массивы 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; }
Скармливаем на проверку Яндексу:
Ура, принято, пройдено около 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 в моем блоге и телеграм
Нет Ответов