Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 01_week/tasks/addition/addition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@


int64_t Addition(int a, int b) {
throw std::runtime_error{"Not implemented"};
return static_cast<int64_t>(a) + static_cast<int64_t>(b);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лишний каст, второй операнд не следует приводить явно, так как он бы преобразовался с помощью неявного каста. Принято использовать такую возможность и не писать явный каст самостоятельно второй раз

}
90 changes: 88 additions & 2 deletions 01_week/tasks/char_changer/char_changer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,91 @@


size_t CharChanger(char array[], size_t size, char delimiter = ' ') {
throw std::runtime_error{"Not implemented"};
}
if (array == nullptr || size == 0) {
return 0;
}

size_t read = 0; // позиция чтения
size_t write = 0; // позиция записи

while (read < size && array[read] != '\0') {
char c = array[read];
char new_char;

// Преобразуем символ по правилам
if (c >= '0' && c <= '9') {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

есть готовые функции для данных проверок, например isdigit, лучше их использовать, так как понятное имя и стандартная функция лучше рукописного кода

new_char = '*';
} else if (c >= 'a' && c <= 'z') {
new_char = c - 'a' + 'A'; // строчная -> прописная
} else if (c >= 'A' && c <= 'Z') {
new_char = c;
} else if (c == ' ') {
new_char = delimiter;
} else {
new_char = '_';
}

// Считаем количество одинаковых символов
size_t count = 1;
size_t next = read + 1;
while (next < size && array[next] != '\0') {
char next_c = array[next];
char next_new_char;

if (next_c >= '0' && next_c <= '9') {
next_new_char = '*';
} else if (next_c >= 'a' && next_c <= 'z') {
next_new_char = next_c - 'a' + 'A';
} else if (next_c >= 'A' && next_c <= 'Z') {
next_new_char = next_c;
} else if (next_c == ' ') {
next_new_char = delimiter;
} else {
next_new_char = '_';
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

дублирование всех проверок, не очень хорошо делать такой копи паст


if (next_new_char == new_char) {
count++;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в таких местах должен быть префиксный инкремент, а постфиксный только там где нужна копия

next++;
} else {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это короткая ветвь корректней сделать if (next_new_char != new_char) break и убрать else

break;
}
}

// Записываем результат
if (new_char == delimiter) {
// Для разделителя пишем только один символ
if (write < size - 1) {
array[write++] = new_char;
}
} else if (count >= 10) {
// 10+ повторений: символ + '0'
if (write < size - 2) {
array[write++] = new_char;
array[write++] = '0';
}
} else if (count > 1) {
// 2-9 повторений: символ + цифра
if (write < size - 2) {
array[write++] = new_char;
array[write++] = '0' + count;
}
} else {
// 1 повторение: только символ
if (write < size - 1) {
array[write++] = new_char;
}
}

read = next; // переходим к следующей группе символов
}

// Завершаем строку
if (write < size) {
array[write] = '\0';
} else if (size > 0) {
array[size - 1] = '\0';
}

return write + 1; // позиция после '\0'
}
52 changes: 51 additions & 1 deletion 01_week/tasks/check_flags/check_flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,55 @@ enum class CheckFlags : uint8_t {
};

void PrintCheckFlags(CheckFlags flags) {
throw std::runtime_error{"Not implemented"};
uint8_t value = static_cast<uint8_t>(flags);

// Проверка на выход за диапазон (максимальное значение ALL)
uint8_t max_value = 63; // TIME | DATE | USER | CERT | KEYS | DEST
if (value > max_value) {
return; // оставляем вывод пустым
}

// Начинаем вывод
printf("[");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

printf это не C++


bool first = true;

// Проверяем каждый флаг
if ((value & static_cast<uint8_t>(CheckFlags::TIME)) != 0) {
if (!first) printf(",");
printf("TIME");
first = false;
}

if ((value & static_cast<uint8_t>(CheckFlags::DATE)) != 0) {
if (!first) printf(",");
printf("DATE");
first = false;
}

if ((value & static_cast<uint8_t>(CheckFlags::USER)) != 0) {
if (!first) printf(",");
printf("USER");
first = false;
}

if ((value & static_cast<uint8_t>(CheckFlags::CERT)) != 0) {
if (!first) printf(",");
printf("CERT");
first = false;
}

if ((value & static_cast<uint8_t>(CheckFlags::KEYS)) != 0) {
if (!first) printf(",");
printf("KEYS");
first = false;
}

if ((value & static_cast<uint8_t>(CheckFlags::DEST)) != 0) {
if (!first) printf(",");
printf("DEST");
first = false;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в данном случае это тоже дублирование, много однотипных действий с разными аргументами


printf("]");
}
51 changes: 51 additions & 0 deletions 01_week/tasks/length_lit/length_lit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Футы в другие единицы
constexpr double operator"" _ft_to_in(long double feet) {
return static_cast<double>(feet * 12.0L);
}

constexpr double operator"" _ft_to_cm(long double feet) {
return static_cast<double>(feet * 30.48L);
}

constexpr double operator"" _ft_to_m(long double feet) {
return static_cast<double>(feet * 0.3048L);
}

// Дюймы в другие единицы
constexpr double operator"" _in_to_ft(long double inches) {
return static_cast<double>(inches / 12.0L);
}

constexpr double operator"" _in_to_cm(long double inches) {
return static_cast<double>(inches * 2.54L);
}

constexpr double operator"" _in_to_m(long double inches) {
return static_cast<double>(inches * 0.0254L);
}

// Сантиметры в другие единицы
constexpr double operator"" _cm_to_ft(long double cm) {
return static_cast<double>(cm / 30.48L);
}

constexpr double operator"" _cm_to_in(long double cm) {
return static_cast<double>(cm / 2.54L);
}

constexpr double operator"" _cm_to_m(long double cm) {
return static_cast<double>(cm / 100.0L);
}

// Метры в другие единицы
constexpr double operator"" _m_to_ft(long double meters) {
return static_cast<double>(meters / 0.3048L);
}

constexpr double operator"" _m_to_in(long double meters) {
return static_cast<double>(meters / 0.0254L);
}

constexpr double operator"" _m_to_cm(long double meters) {
return static_cast<double>(meters * 100.0L);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

использование magic value не принято в коде, удобнее сделать константы с понятными именами и уже их использовать в коде, безымянный namespace для их объединения как вариант использвоания

}
26 changes: 25 additions & 1 deletion 01_week/tasks/print_bits/print_bits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,29 @@


void PrintBits(long long value, size_t bytes) {
throw std::runtime_error{"Not implemented"};
// Проверка допустимого диапазона размера
if (bytes == 0 || bytes > 8) {
return;
}

// Выводим префикс "0b"
printf("0b");

// Проходим по всем битам от старшего к младшему
for (int i = static_cast<int>(bytes * 8) - 1; i >= 0; i--) {
// Получаем i-тый бит
if (value & (1LL << i)) {
printf("1");
} else {
printf("0");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это должен быть тернарный оператор


// Добавляем апостроф каждые 8 бит (кроме последней группы)
if (i > 0 && i % 8 == 0) {
printf("'");
}
}

// Перевод строки в конце
printf("\n");
}
48 changes: 46 additions & 2 deletions 01_week/tasks/quadratic/quadratic.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,50 @@
#include <stdexcept>

#include <cmath>
#include <stdexcept>

void SolveQuadratic(int a, int b, int c) {
throw std::runtime_error{"Not implemented"};
std::cout << std::setprecision(6);

// Случай бесконечных решений: 0*x² + 0*x + 0 = 0
if (a == 0 && b == 0 && c == 0) {
std::cout << "infinite solutions" << std::endl;
return;
}

// Линейное уравнение: 0*x² + b*x + c = 0
if (a == 0) {
if (b == 0) {
// 0*x + c = 0, где c ≠ 0 - нет решений
std::cout << "no solutions" << std::endl;
} else {
// b*x + c = 0 → x = -c/b
double x = -static_cast<double>(c) / b;
std::cout << x << std::endl;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в данном случае также нужно было использовать стиль первого решения, общее условие и ветвь с выходом, несколько больше сравнений, но компактнее и понятнее

return;
}

// Квадратное уравнение: a*x² + b*x + c = 0, где a ≠ 0
double discriminant = static_cast<double>(b) * b - 4.0 * a * c;

if (discriminant < 0) {
// Отрицательный дискриминант - нет действительных корней
std::cout << "no solutions" << std::endl;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут должен быть return, поскольку не придется листать оставшийся код, чтобы понять, что больше ничего не добавляется, а далее везде убраны else,

} else if (discriminant == 0) {
// Нулевой дискриминант - один корень
double x = -static_cast<double>(b) / (2.0 * a);
std::cout << x << std::endl;
} else {
// Положительный дискриминант - два корня
double sqrt_d = std::sqrt(discriminant);
double x1 = (-b - sqrt_d) / (2.0 * a);
double x2 = (-b + sqrt_d) / (2.0 * a);

// Убеждаемся, что x1 < x2
if (x1 > x2) {
std::swap(x1, x2);
}

std::cout << x1 << " " << x2 << std::endl;
}
}
20 changes: 18 additions & 2 deletions 01_week/tasks/rms/rms.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
#include <cstdef>
#include <stdexcept>

#include <cmath>

double CalculateRMS(double values[], size_t size) {
throw std::runtime_error{"Not implemented"};
// Обработка пустого массива
if (size == 0) {
return 0.0;
}

// Сумма квадратов элементов
double sum_of_squares = 0.0;

for (size_t i = 0; i < size; ++i) {
sum_of_squares += values[i] * values[i];
}

// Среднее значение квадратов
double mean_of_squares = sum_of_squares / size;

// Корень из среднего значения квадратов
return std::sqrt(mean_of_squares);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mean_of_squares используется только в одном месте, заводить переменную излишне, можно подставить выражение в сразу в функцию квадратного корня

}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

комментарии тут излишне, по именам и коду понятно что происходит, лишнего не нужно писать

23 changes: 21 additions & 2 deletions 02_week/tasks/func_array/func_array.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
#include <stdexcept>

// Тип для указателя на функцию операции
using FuncType = double(*)(double, double);

double ApplyOperations(double a, double b /* other arguments */) {
throw std::runtime_error{"Not implemented"};
double ApplyOperations(double a, double b, FuncType operations[], size_t size) {
// В случае пустого массива операций возвращаем 0.0
if (size == 0) {
return 0.0;
}

double sum = 0.0;

// Чистый цикл без использования STL алгоритмов
for (size_t i = 0; i < size; ++i) {
// Проверяем, что указатель на функцию не равен nullptr
if (operations[i] != nullptr) {
// Выполняем операцию и добавляем результат к сумме
sum += operations[i](a, b);
}
// Если operations[i] == nullptr, просто пропускаем (добавляем 0 к сумме)
}

return sum;
}
27 changes: 25 additions & 2 deletions 02_week/tasks/last_of_us/last_of_us.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
#include <stdexcept>


/* return_type */ FindLastElement(/* ptr_type */ begin, /* ptr_type */ end, /* func_type */ predicate) {
throw std::runtime_error{"Not implemented"};
// Тип для указателя на функцию-предикат
using Predicate = bool(*)(int);

const int* FindLastElement(const int* begin, const int* end, Predicate predicate) {
// Проверка на некорректные указатели
if (begin == nullptr || end == nullptr) {
return end;
}

// Проверка на некорректный диапазон (begin > end)
if (begin > end) {
return end;
}

// Указатель для последнего найденного элемента
const int* last_found = end; // Изначально указывает за последний элемент

// Проходим по массиву с начала до конца
for (const int* current = begin; current < end; ++current) {
if (predicate(*current)) {
last_found = current; // Обновляем указатель на последний найденный элемент
}
}

return last_found;
}
Loading
Loading