diff --git a/c/solution3.c b/c/solution3.c deleted file mode 100644 index ca665a4..0000000 --- a/c/solution3.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include // atoi, malloc - -void ten_to_bin(int count, long long x, char *mask) { - int i = 0; - while (i < count) { - mask[i] = (x & 1) + '0'; // Побитовое И вместо % 2 - mask[i+1] = '\0'; - x >>= 1; // Побитовый сдвиг вправо вместо / 2 - i++; - } -} - -/* - * Оптимизированный подсчет суммы: - * Проверяем биты числа x напрямую. Если j-й бит равен 1, - * прибавляем numbers[j] к сумме. - */ -long long calculate_sum(int count, int *numbers, long long x) { - long long sum = 0; - for (int j = 0; j < count; j++) { - // Проверяем, установлен ли j-й бит в числе x - if ((x >> j) & 1) { - sum += numbers[j]; - } - } - return sum; -} - -void find_sum(int count, long long target, int *numbers, char *mask) { - // 1LL << count — это 2 в степени count (макс. 62 для long long) - long long total_combinations = (1LL << count); - printf("Total combinations: %lld\n", total_combinations); - - for (long long i = 0; i < total_combinations; i++) { - long long current_sum = 0; - - // Внутренний цикл: проверяем биты числа i напрямую - for (int j = 0; j < count; j++) { - // Если j-й бит числа i равен 1, прибавляем numbers[j] - if ((i >> j) & 1) { - current_sum += numbers[j]; - } - } - - if (current_sum == target) { - ten_to_bin(count, i, mask); - printf("OK: %s\n", mask); - return; - } - } - printf("NO: not found.\n"); -} - -// gcc -O3 solution3.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 - char *mask = - calloc(count + 1, sizeof(char)); // +1 для символа конца строки '\0' - - // 4. Данные готовы, начинаем считать - find_sum(count, target, numbers, mask); - - // 5. Освобождаем память - free(mask); - free(numbers); - return 0; -} diff --git a/c/solution4.c b/c/solution4.c deleted file mode 100644 index d531166..0000000 --- a/c/solution4.c +++ /dev/null @@ -1,117 +0,0 @@ -#include -#include // atoi, malloc - -void ten_to_bin(int count, long long x, char *mask) { - int i = 0; - while (i < count) { - mask[i] = (x & 1) + '0'; // Побитовое И вместо % 2 - mask[i+1] = '\0'; - x >>= 1; // Побитовый сдвиг вправо вместо / 2 - i++; - } -} - -long long calculate_sum(int count, int *numbers, long long x) { - long long sum = 0; - for (int j = 0; j < count; j++) { - // Проверяем, установлен ли j-й бит в числе x - if ((x >> j) & 1) { - sum += numbers[j]; - } - } - return sum; -} - -void find_sum(int count, long long target, int *numbers, char *mask) { - long long total_combinations = (1LL << count); - printf("Total combinations: %lld\n", total_combinations); - - for (long long i = 0; i < total_combinations; i++) { - long long current_sum = 0; - - // Развертывание цикла (Unrolling) + Избавление от if (Branchless) - // Процессор будет выполнять эти операции параллельно в конвейере - int j = 0; - - // Разворачиваем по 2 шага для ускорения - for (; j <= count - 2; j += 2) { - current_sum += (long long)numbers[j] * ((i >> j) & 1); - current_sum += (long long)numbers[j + 1] * ((i >> (j + 1)) & 1); - } - - // Добираем оставшиеся элементы, если count не кратен 2 - for (; j < count; j++) { - current_sum += (long long)numbers[j] * ((i >> j) & 1); - } - - if (current_sum == target) { - ten_to_bin(count, i, mask); - printf("OK: %s\n", mask); - return; - } - } - printf("NO: not found.\n"); -} - -void find_sum_old(int count, long long target, int *numbers, char *mask) { - // 1LL << count — это 2 в степени count (макс. 62 для long long) - long long total_combinations = (1LL << count); - printf("Total combinations: %lld\n", total_combinations); - - for (long long i = 0; i < total_combinations; i++) { - long long current_sum = 0; - - // Внутренний цикл: проверяем биты числа i напрямую - for (int j = 0; j < count; j++) { - // Используем умножение на бит вместо if, чтобы избежать ошибок в предсказании перехода - current_sum += numbers[j] * ((i >> j) & 1); - } - - if (current_sum == target) { - ten_to_bin(count, i, mask); - printf("OK: %s\n", mask); - return; - } - } - printf("NO: not found.\n"); -} - -// gcc -O3 -march=bdver2 solution4.c -o solution -// gcc -O3 solution4.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 - char *mask = - calloc(count + 1, sizeof(char)); // +1 для символа конца строки '\0' - - // 4. Данные готовы, начинаем считать - find_sum(count, target, numbers, mask); - - // 5. Освобождаем память - free(mask); - free(numbers); - return 0; -}