Replaced subject resolutions of level-2 with backtracking
This commit is contained in:
parent
0ec1385e07
commit
94ff9315d7
@ -1,84 +1,131 @@
|
||||
#include "n_queens.h"
|
||||
#include <unistd.h> // write
|
||||
#include <stdlib.h> // malloc, free, atoi
|
||||
#include <stdio.h> // fprintf, stderr (permitido para erros)
|
||||
|
||||
void print_number(int n)
|
||||
// Função auxiliar para escrever um único caractere no stdout
|
||||
void ft_putchar(char c)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (n >= 10)
|
||||
print_number(n / 10);
|
||||
c = '0' + (n % 10);
|
||||
write(1, &c, 1);
|
||||
}
|
||||
|
||||
void print_solution(int *queens, int n)
|
||||
// Função auxiliar para escrever um número inteiro no stdout
|
||||
void ft_putnbr(int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < n)
|
||||
if (n >= 10)
|
||||
{
|
||||
if (i > 0)
|
||||
write(1, " ", 1);
|
||||
print_number(queens[i]);
|
||||
i++;
|
||||
ft_putnbr(n / 10);
|
||||
}
|
||||
write(1, "\n", 1);
|
||||
ft_putchar((n % 10) + '0');
|
||||
}
|
||||
|
||||
int is_safe(int *queens, int row, int col, int n)
|
||||
// Imprime a solução no formato "p1 p2 p3 ..."
|
||||
void print_solution(int *board, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)n;
|
||||
i = 0;
|
||||
while (i < row)
|
||||
int i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
if (queens[i] == col)
|
||||
ft_putnbr(board[i]);
|
||||
if (i < n - 1)
|
||||
ft_putchar(' ');
|
||||
i++;
|
||||
}
|
||||
ft_putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
int ft_abs(int nbr)
|
||||
{
|
||||
if (nbr < 0)
|
||||
return (nbr * -1);
|
||||
else
|
||||
return (nbr);
|
||||
}
|
||||
// Verifica se é seguro colocar uma rainha na posição (row, col)
|
||||
// Só precisamos verificar as colunas à esquerda da coluna atual
|
||||
int is_safe(int *board, int n, int row, int col)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
(void)n;
|
||||
while (i < col)
|
||||
{
|
||||
// 1. Verifica se há outra rainha na mesma linha
|
||||
if (board[i] == row)
|
||||
return (0);
|
||||
if (queens[i] - i == col - row)
|
||||
return (0);
|
||||
if (queens[i] + i == col + row)
|
||||
|
||||
// 2. Verifica as diagonais
|
||||
// abs(board[i] - row) == abs(i - col)
|
||||
// Como col > i, abs(i - col) é (col - i)
|
||||
if (ft_abs(board[i] - row) == (col - i))
|
||||
return (0);
|
||||
i++;
|
||||
}
|
||||
// Se passou por todas as verificações, a posição é segura
|
||||
return (1);
|
||||
}
|
||||
|
||||
void solve_nqueens(int *queens, int row, int n)
|
||||
// A função principal de backtracking
|
||||
void solve(int *board, int n, int col)
|
||||
{
|
||||
int col;
|
||||
|
||||
if (row == n)
|
||||
// Caso base: Se todas as rainhas foram colocadas (chegamos ao final do tabuleiro)
|
||||
if (col == n)
|
||||
{
|
||||
print_solution(queens, n);
|
||||
return ;
|
||||
print_solution(board, n);
|
||||
return;
|
||||
}
|
||||
col = 0;
|
||||
while (col < n)
|
||||
|
||||
// Tenta colocar uma rainha em cada linha da coluna atual
|
||||
int row = 0;
|
||||
while (row < n)
|
||||
{
|
||||
if (is_safe(queens, row, col, n))
|
||||
// Verifica se a posição (row, col) é segura
|
||||
if (is_safe(board, n, row, col))
|
||||
{
|
||||
queens[row] = col;
|
||||
solve_nqueens(queens, row + 1, n);
|
||||
// Coloca a rainha
|
||||
board[col] = row;
|
||||
|
||||
// Chama a função recursivamente para a próxima coluna
|
||||
solve(board, n, col + 1);
|
||||
|
||||
// O backtracking é implícito: na próxima iteração do loop,
|
||||
// board[col] será sobrescrito com um novo valor de 'row'.
|
||||
// Não precisamos de "remover" a rainha explicitamente.
|
||||
}
|
||||
col++;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int n;
|
||||
int *queens;
|
||||
int *board;
|
||||
int n;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
// Usar fprintf com stderr é permitido para mensagens de erro
|
||||
fprintf(stderr, "Usage: %s n\n", argv[0]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
n = atoi(argv[1]);
|
||||
if (n <= 0)
|
||||
{
|
||||
return (0); // Não faz nada para n <= 0, como esperado
|
||||
}
|
||||
|
||||
// Aloca memória para o tabuleiro. board[col] = row
|
||||
board = (int *)malloc(sizeof(int) * n);
|
||||
if (!board)
|
||||
{
|
||||
fprintf(stderr, "Memory allocation failed\n");
|
||||
return (1);
|
||||
queens = (int *)malloc(sizeof(int) * n);
|
||||
if (!queens)
|
||||
return (1);
|
||||
solve_nqueens(queens, 0, n);
|
||||
free(queens);
|
||||
}
|
||||
|
||||
// Inicia o processo de backtracking a partir da primeira coluna (col = 0)
|
||||
solve(board, n, 0);
|
||||
|
||||
// Liberta a memória alocada
|
||||
free(board);
|
||||
return (0);
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
#ifndef N_QUEENS_H
|
||||
# define N_QUEENS_H
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <stdio.h>
|
||||
|
||||
int is_safe(int *queens, int row, int col, int n);
|
||||
void solve_nqueens(int *queens, int row, int n);
|
||||
void print_solution(int *queens, int n);
|
||||
void print_number(int n);
|
||||
|
||||
#endif
|
||||
93
level-2/n_queens/n_queens_clean.c
Normal file
93
level-2/n_queens/n_queens_clean.c
Normal file
@ -0,0 +1,93 @@
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void ft_putchar(char c)
|
||||
{
|
||||
write(1, &c, 1);
|
||||
}
|
||||
|
||||
void ft_putnbr(int n)
|
||||
{
|
||||
if (n >= 10)
|
||||
ft_putnbr(n / 10);
|
||||
ft_putchar((n % 10) + '0');
|
||||
}
|
||||
|
||||
void print_solution(int *board, int n)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
ft_putnbr(board[i]);
|
||||
if (i < n - 1)
|
||||
ft_putchar(' ');
|
||||
i++;
|
||||
}
|
||||
ft_putchar('\n');
|
||||
}
|
||||
|
||||
int ft_abs(int nbr)
|
||||
{
|
||||
if (nbr < 0)
|
||||
return (nbr * -1);
|
||||
else
|
||||
return (nbr);
|
||||
}
|
||||
|
||||
int is_safe(int *board, int n, int row, int col)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
(void)n;
|
||||
while (i < col)
|
||||
{
|
||||
if (board[i] == row)
|
||||
return (0);
|
||||
if (ft_abs(board[i] - row) == (col - i))
|
||||
return (0);
|
||||
i++;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void solve(int *board, int n, int col)
|
||||
{
|
||||
if (col == n)
|
||||
return(print_solution(board, n));
|
||||
|
||||
int row = 0;
|
||||
while (row < n)
|
||||
{
|
||||
if (is_safe(board, n, row, col))
|
||||
{
|
||||
board[col] = row;
|
||||
solve(board, n, col + 1);
|
||||
}
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int *board;
|
||||
int n;
|
||||
|
||||
if (argc != 2)
|
||||
return (fprintf(stderr, "Usage: %s n\n", argv[0]), 1);
|
||||
|
||||
n = atoi(argv[1]);
|
||||
if (n <= 0)
|
||||
return (0);
|
||||
|
||||
board = (int *)malloc(sizeof(int) * n);
|
||||
if (!board)
|
||||
{
|
||||
fprintf(stderr, "Memory allocation failed\n");
|
||||
return (1);
|
||||
}
|
||||
solve(board, n, 0);
|
||||
free(board);
|
||||
return (0);
|
||||
}
|
||||
94
level-2/permutations/permutation_clean.c
Normal file
94
level-2/permutations/permutation_clean.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <unistd.h> // write
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
int ft_strlen(const char *s)
|
||||
{
|
||||
int len = 0;
|
||||
while (s[len])
|
||||
len++;
|
||||
return (len);
|
||||
}
|
||||
|
||||
void print_solution(const char *s)
|
||||
{
|
||||
write(1, s, ft_strlen(s));
|
||||
write(1, "\n", 1);
|
||||
}
|
||||
|
||||
void ft_swap(char *a, char *b)
|
||||
{
|
||||
char temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
void sort_string(char *str, int n)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
i = 0;
|
||||
while (i < n - 1)
|
||||
{
|
||||
j = 0;
|
||||
while (j < n - i - 1)
|
||||
{
|
||||
if (str[j] > str[j + 1])
|
||||
ft_swap(&str[j], &str[j + 1]);
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void generate_permutations(char *original_str, char *current_perm, int *used, int n, int k)
|
||||
{
|
||||
if (k == n)
|
||||
{
|
||||
print_solution(current_perm);
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
if (used[i] == 0)
|
||||
{
|
||||
current_perm[k] = original_str[i];
|
||||
used[i] = 1;
|
||||
generate_permutations(original_str, current_perm, used, n, k + 1);
|
||||
used[i] = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2 || !argv[1][0])
|
||||
return (0);
|
||||
|
||||
int n = ft_strlen(argv[1]);
|
||||
char *original_str = argv[1];
|
||||
|
||||
sort_string(original_str, n);
|
||||
|
||||
char *current_perm = (char *)malloc(sizeof(char) * (n + 1));
|
||||
if (!current_perm)
|
||||
return (1);
|
||||
current_perm[n] = '\0';
|
||||
|
||||
int *used = (int *)calloc(sizeof(int) * n);
|
||||
if (!used)
|
||||
{
|
||||
free(current_perm);
|
||||
return (1);
|
||||
}
|
||||
|
||||
generate_permutations(original_str, current_perm, used, n, 0);
|
||||
|
||||
free(current_perm);
|
||||
free(used);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1,98 +1,132 @@
|
||||
#include "permutations.h"
|
||||
#include <unistd.h> // write
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
int ft_strlen(char *str)
|
||||
// Função auxiliar para obter o comprimento de uma string
|
||||
int ft_strlen(const char *s)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
while (str[len])
|
||||
int len = 0;
|
||||
while (s[len])
|
||||
len++;
|
||||
return (len);
|
||||
}
|
||||
|
||||
void ft_swap(char *a, char *b)
|
||||
// Função auxiliar para imprimir uma string seguida de uma nova linha
|
||||
void print_solution(const char *s)
|
||||
{
|
||||
char temp;
|
||||
write(1, s, ft_strlen(s));
|
||||
write(1, "\n", 1);
|
||||
}
|
||||
|
||||
temp = *a;
|
||||
// Função auxiliar para trocar dois caracteres (usada na ordenação)
|
||||
void ft_swap(char *a, char *b)
|
||||
{
|
||||
char temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
void ft_sort_string(char *str)
|
||||
// Função para ordenar a string de entrada (Bubble Sort simples)
|
||||
// Isso é crucial para garantir que as permutações sejam geradas em ordem alfabética.
|
||||
void sort_string(char *str, int n)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int len;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
len = ft_strlen(str);
|
||||
i = 0;
|
||||
while (i < len - 1)
|
||||
while (i < n - 1)
|
||||
{
|
||||
j = i + 1;
|
||||
while (j < len)
|
||||
j = 0;
|
||||
while (j < n - i - 1)
|
||||
{
|
||||
if (str[i] > str[j])
|
||||
ft_swap(&str[i], &str[j]);
|
||||
if (str[j] > str[j + 1])
|
||||
ft_swap(&str[j], &str[j + 1]);
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void ft_reverse(char *str, int start, int end)
|
||||
// A função principal de backtracking, análoga à sua função `solve`
|
||||
// Parâmetros:
|
||||
// - original_str: A string original, já ordenada
|
||||
// - current_perm: A permutação que estamos construindo (o "tabuleiro")
|
||||
// - used: Um array que marca quais caracteres da string original já foram usados
|
||||
// - n: O tamanho da string
|
||||
// - k: A posição atual que estamos preenchendo em `current_perm` (análogo a `col`)
|
||||
void generate_permutations(char *original_str, char *current_perm, int *used, int n, int k)
|
||||
{
|
||||
while (start < end)
|
||||
// Caso base: Se todas as posições foram preenchidas (k == n),
|
||||
// análogo a `if (col == n)` no N-Queens.
|
||||
if (k == n)
|
||||
{
|
||||
ft_swap(&str[start], &str[end]);
|
||||
start++;
|
||||
end--;
|
||||
print_solution(current_perm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int next_permutation(char *str, int len)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
i = len - 2;
|
||||
while (i >= 0 && str[i] >= str[i + 1])
|
||||
i--;
|
||||
if (i < 0)
|
||||
return (0);
|
||||
j = len - 1;
|
||||
while (str[j] <= str[i])
|
||||
j--;
|
||||
ft_swap(&str[i], &str[j]);
|
||||
ft_reverse(str, i + 1, len - 1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *str;
|
||||
char *copy;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
if (argc != 2)
|
||||
return (1);
|
||||
str = argv[1];
|
||||
len = ft_strlen(str);
|
||||
copy = malloc(sizeof(char) * (len + 1));
|
||||
if (!copy)
|
||||
return (1);
|
||||
i = 0;
|
||||
while (i < len)
|
||||
// Tenta colocar cada caractere da string original na posição 'k' atual
|
||||
int i = 0;
|
||||
while (i < n)
|
||||
{
|
||||
copy[i] = str[i];
|
||||
// Verifica se a "jogada" é válida, análogo ao `is_safe`.
|
||||
// A condição é: o i-ésimo caractere da string original ainda não foi usado?
|
||||
if (used[i] == 0)
|
||||
{
|
||||
// "Coloca a peça no tabuleiro":
|
||||
// 1. Coloca o caractere na permutação atual
|
||||
current_perm[k] = original_str[i];
|
||||
// 2. Marca este caractere como usado
|
||||
used[i] = 1;
|
||||
|
||||
// Chama a função recursivamente para a próxima posição (k + 1),
|
||||
// análogo a `solve(board, n, col + 1)`
|
||||
generate_permutations(original_str, current_perm, used, n, k + 1);
|
||||
|
||||
// Backtracking: Desfaz a jogada para que este caractere possa ser
|
||||
// usado em uma posição diferente na próxima ramificação da recursão.
|
||||
// Isso é crucial e um pouco mais explícito que no seu N-Queens.
|
||||
used[i] = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
copy[len] = '\0';
|
||||
ft_sort_string(copy);
|
||||
puts(copy);
|
||||
while (next_permutation(copy, len))
|
||||
puts(copy);
|
||||
free(copy);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2 || !argv[1][0])
|
||||
{
|
||||
// Não faz nada se não houver exatamente um argumento ou se for uma string vazia.
|
||||
return (0);
|
||||
}
|
||||
|
||||
int n = ft_strlen(argv[1]);
|
||||
char *original_str = argv[1]; // Não precisamos de cópia, podemos ordenar o argumento
|
||||
|
||||
// 1. Ordena a string de entrada para garantir a saída em ordem alfabética
|
||||
sort_string(original_str, n);
|
||||
|
||||
// 2. Aloca memória para a permutação que será construída
|
||||
char *current_perm = (char *)malloc(sizeof(char) * (n + 1));
|
||||
if (!current_perm)
|
||||
return (1);
|
||||
current_perm[n] = '\0'; // Garante a terminação da string
|
||||
|
||||
// 3. Aloca memória para o array de "usados" e o inicializa com 0
|
||||
// `calloc` é útil aqui pois inicializa a memória com zeros.
|
||||
int *used = (int *)malloc(sizeof(int) * n);
|
||||
if (!used)
|
||||
{
|
||||
free(current_perm);
|
||||
return (1);
|
||||
}
|
||||
for (int i = 0; i < n; i++)
|
||||
used[i] = 0;
|
||||
|
||||
// Inicia o processo de backtracking a partir da primeira posição (k = 0)
|
||||
generate_permutations(original_str, current_perm, used, n, 0);
|
||||
|
||||
// Liberta a memória alocada
|
||||
free(current_perm);
|
||||
free(used);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
#ifndef PERMUTATIONS_H
|
||||
# define PERMUTATIONS_H
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <stdio.h>
|
||||
|
||||
void ft_swap(char *a, char *b);
|
||||
void ft_sort_string(char *str);
|
||||
void ft_reverse(char *str, int start, int end);
|
||||
int next_permutation(char *str, int len);
|
||||
int ft_strlen(char *str);
|
||||
|
||||
#endif
|
||||
@ -1,5 +1,8 @@
|
||||
#include "powerset.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Função auxiliar para imprimir um subconjunto encontrado.
|
||||
// A ordem dos elementos é mantida porque os adicionamos na ordem original.
|
||||
void print_subset(int *subset, int size)
|
||||
{
|
||||
int i;
|
||||
@ -15,59 +18,89 @@ void print_subset(int *subset, int size)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void find_subsets(int *set, int set_size, int target, int *subset,
|
||||
int subset_size, int index)
|
||||
/**
|
||||
* Função recursiva de backtracking para encontrar os subconjuntos.
|
||||
*
|
||||
* @param target A soma restante que precisamos alcançar.
|
||||
* @param set O conjunto original de números.
|
||||
* @param set_size O tamanho do conjunto original.
|
||||
* @param index O índice do elemento atual que estamos considerando no conjunto.
|
||||
* @param current_path O subconjunto que estamos construindo atualmente.
|
||||
* @param path_len O número de elementos no subconjunto atual.
|
||||
*/
|
||||
void find_subsets(int target, int *set, int set_size, int index, int *current_path, int path_len)
|
||||
{
|
||||
int current_sum;
|
||||
int i;
|
||||
|
||||
if (index == set_size)
|
||||
// Caso base 1: Encontramos um subconjunto cuja soma é igual ao alvo original.
|
||||
if (target == 0)
|
||||
{
|
||||
current_sum = 0;
|
||||
i = 0;
|
||||
while (i < subset_size)
|
||||
{
|
||||
current_sum += subset[i];
|
||||
i++;
|
||||
}
|
||||
if (current_sum == target)
|
||||
print_subset(subset, subset_size);
|
||||
return ;
|
||||
print_subset(current_path, path_len);
|
||||
// Retornamos porque encontramos uma solução válida para este caminho.
|
||||
return;
|
||||
}
|
||||
find_subsets(set, set_size, target, subset, subset_size, index + 1);
|
||||
subset[subset_size] = set[index];
|
||||
find_subsets(set, set_size, target, subset, subset_size + 1, index + 1);
|
||||
|
||||
// Caso base 2: Se já consideramos todos os números, não há mais nada a fazer.
|
||||
if (index >= set_size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Decisão Recursiva ---
|
||||
|
||||
// Escolha 1: INCLUIR o elemento atual (set[index]) no subconjunto.
|
||||
// Adicionamos o elemento ao nosso caminho.
|
||||
current_path[path_len] = set[index];
|
||||
// Chamamos a função para o próximo elemento, com o alvo reduzido.
|
||||
find_subsets(target - set[index], set, set_size, index + 1, current_path, path_len + 1);
|
||||
|
||||
// Escolha 2: NÃO INCLUIR o elemento atual (set[index]).
|
||||
// Este é o passo de "backtrack". Nós simplesmente ignoramos o elemento atual
|
||||
// e passamos para o próximo, sem alterar o caminho ou o alvo.
|
||||
find_subsets(target, set, set_size, index + 1, current_path, path_len);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int *set;
|
||||
int *subset;
|
||||
int target;
|
||||
int set_size;
|
||||
int i;
|
||||
int target;
|
||||
int *numbers;
|
||||
int *path;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
// Deve haver pelo menos um alvo (n). O conjunto (s) pode ser vazio.
|
||||
if (argc < 2)
|
||||
return (1);
|
||||
return (0);
|
||||
|
||||
target = atoi(argv[1]);
|
||||
set_size = argc - 2;
|
||||
set = malloc(sizeof(int) * set_size);
|
||||
if (!set)
|
||||
return (1);
|
||||
subset = malloc(sizeof(int) * set_size);
|
||||
if (!subset)
|
||||
size = argc - 2;
|
||||
|
||||
// Aloca memória para o conjunto de números de entrada.
|
||||
numbers = (int *)malloc(sizeof(int) * size);
|
||||
if (!numbers)
|
||||
return (1); // Erro de malloc
|
||||
|
||||
// Aloca memória para o array que armazenará o subconjunto atual.
|
||||
// O tamanho máximo de um subconjunto é o tamanho do conjunto original.
|
||||
path = (int *)malloc(sizeof(int) * size);
|
||||
if (!path)
|
||||
{
|
||||
free(set);
|
||||
return (1);
|
||||
free(numbers);
|
||||
return (1); // Erro de malloc
|
||||
}
|
||||
|
||||
// Converte os argumentos da linha de comando em um array de inteiros.
|
||||
i = 0;
|
||||
while (i < set_size)
|
||||
while (i < size)
|
||||
{
|
||||
set[i] = atoi(argv[i + 2]);
|
||||
numbers[i] = atoi(argv[i + 2]);
|
||||
i++;
|
||||
}
|
||||
find_subsets(set, set_size, target, subset, 0, 0);
|
||||
free(set);
|
||||
free(subset);
|
||||
|
||||
// Inicia a busca recursiva a partir do primeiro elemento (índice 0).
|
||||
find_subsets(target, numbers, size, 0, path, 0);
|
||||
|
||||
// Libera a memória alocada.
|
||||
free(numbers);
|
||||
free(path);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef POWERSET_H
|
||||
# define POWERSET_H
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <stdio.h>
|
||||
|
||||
void find_subsets(int *set, int set_size, int target, int *subset,
|
||||
int subset_size, int index);
|
||||
void print_subset(int *subset, int size);
|
||||
|
||||
#endif
|
||||
68
level-2/powerset/powerset_clean.c
Normal file
68
level-2/powerset/powerset_clean.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void print_subset(int *subset, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
printf("%d", subset[i]);
|
||||
if (i < size - 1)
|
||||
printf(" ");
|
||||
i++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void find_subsets(int target, int *set, int set_size, int index, int *current_path, int path_len)
|
||||
{
|
||||
if (target == 0)
|
||||
return (print_subset(current_path, path_len));
|
||||
|
||||
if (index >= set_size)
|
||||
return;
|
||||
|
||||
current_path[path_len] = set[index];
|
||||
find_subsets(target - set[index], set, set_size, index + 1, current_path, path_len + 1);
|
||||
find_subsets(target, set, set_size, index + 1, current_path, path_len);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int target;
|
||||
int *numbers;
|
||||
int *path;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
if (argc < 2)
|
||||
return (0);
|
||||
|
||||
target = atoi(argv[1]);
|
||||
size = argc - 2;
|
||||
|
||||
numbers = (int *)malloc(sizeof(int) * size);
|
||||
if (!numbers)
|
||||
return (1);
|
||||
|
||||
path = (int *)malloc(sizeof(int) * size);
|
||||
if (!path)
|
||||
{
|
||||
free(numbers);
|
||||
return (1);
|
||||
}
|
||||
i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
numbers[i] = atoi(argv[i + 2]);
|
||||
i++;
|
||||
}
|
||||
find_subsets(target, numbers, size, 0, path, 0);
|
||||
|
||||
free(numbers);
|
||||
free(path);
|
||||
|
||||
return (0);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user