diff --git a/c/solution1_comments.c b/c/solution1_comments.c new file mode 100644 index 0000000..f6dc98a --- /dev/null +++ b/c/solution1_comments.c @@ -0,0 +1,121 @@ +#include +#include // pow +#include // atoi, malloc + +/* + * name: ten_to_bin + * + * Описание: Преобразует целое число в строку из символов '0' и '1' (двоичный + * вид). Биты записываются в обратном порядке (от младшего к старшему). В конец + * строки всегда добавляется нулевой символ '\0'. + * + * @param count - Максимальное количество бит для обработки. + * @param x - Число для конвертации (передается по значению). + * @param mask - Указатель на буфер, куда записывается строка (размер >= count + * + 1). + * + * @return void (результат сохраняется напрямую в памяти по адресу mask). + */ +void ten_to_bin(int count, int x, char *mask) { + int i = 0; + while (x != 0 && i < count) { + // Превращаем 0 в '0' (код 48), 1 в '1' (код 49) + mask[i] = (x % 2) + '0'; + mask[i+1] = '\0'; + x /= 2; + i++; + } +} + +/* + * name: calculate_sum + * + * Описание: Вычисляет сумму чисел из массива numbers, соответствующих + * символу '1' в битовой строке mask. + * + * @param count - Максимальное количество элементов для проверки. + * @param numbers - Указатель на массив исходных целых чисел. + * @param mask - Строка (char*), где '1' означает "включить число в сумму", + * а '0' — "пропустить". + * + * @return int - Итоговая сумма выбранных чисел. + */ +int calculate_sum(int count, int *numbers, char *mask) { + int x = 0; + for (int i = 0; mask[i] != '\0' && i < count; i++) { + if (mask[i] == '1') { + x += numbers[i]; + } + } + return x; +} + +/* + * name: find_sum + * + * Описание: Перебирает все возможные комбинации чисел (через двоичные маски), + * пока не найдет ту, сумма которой равна target. + * При нахождении выводит маску в консоль и завершает работу. + * + * @param count - Количество чисел в исходном массиве. + * @param target - Целевая сумма, которую нужно получить. + * @param numbers - Указатель на массив исходных чисел. + * @param mask - Буфер для хранения и вывода текущей битовой комбинации. + * + * @return void (результат выводится в стандартный поток вывода printf). + */ +void find_sum(int count, long long target, int *numbers, char *mask) { + long long total_combinations = pow(2, count) - 1; + printf("Total combinations: %lld\n", total_combinations); + + for (int i = 0; i <= total_combinations; i++) { + ten_to_bin(count, i, mask); + long long current_sum = calculate_sum(count, numbers, mask); + + if (current_sum == target) { + // Печать результата + printf("OK: %s\n", mask); + return; + } + } + printf("NO: not found.\n"); +} + +// gcc -O3 solution1.c -o solution -lm +// ./solution 477550 15800 1525 35300 19410 25000 15800 1525 35300 19410 25000 +// 15800 1525 35300 19410 25000 15800 1525 35300 19410 25000 15800 1525 35300 +// 19410 25000 +int main(int argc, char *argv[]) { + // 1. Валидация ввода + if (argc < 5) { + printf("ER: input parameters \n"); + return 1; + } + + if (argc > 30) { + printf("ER: input parameters \n"); + return 1; + } + + // 2. Формирование массива int + long long target = atoi(argv[1]); // Требуемая сумма + int count = argc - 2; // Количество переданных чисел + int *numbers = malloc(count * sizeof(int)); // Массив чисел + + for (int i = 0; i < count; i++) { + // Преобразуем каждый аргумент (начиная с argv[2]) в int + numbers[i] = atoi(argv[i + 2]); + } + + // 3. Формирование массива char + // +1 для символа конца строки '\0' + char *mask = calloc(count + 1, sizeof(char)); + + // 4. Данные готовы, начинаем считать + find_sum(count, target, numbers, mask); + + // 5. Освобождаем память + free(mask); + free(numbers); + return 0; +}