diff --git a/level-2/permutations/permutations.c b/level-2/permutations/permutations.c index 73d8236..f5aa136 100644 --- a/level-2/permutations/permutations.c +++ b/level-2/permutations/permutations.c @@ -1,132 +1,60 @@ -#include // write -#include // malloc, free +#include +#include -// Função auxiliar para obter o comprimento de uma string -int ft_strlen(const char *s) +int length; +char *set; +char *permutation; + +int ft_strlen(char *s) { - int len = 0; - while (s[len]) - len++; - return (len); + int i = 0; + while(s[i]) + i++; + return (i); } -// Função auxiliar para imprimir uma string seguida de uma nova linha -void print_solution(const char *s) + +void permutations(int index, char *used) { - write(1, s, ft_strlen(s)); - write(1, "\n", 1); + if (index == length) + { + printf("%s\n", permutation); + return ; + } + + int i = 0; + while (i < length) + { + if (used[i] == '0') + { + permutation[index] = set[i]; + used[i] = '1'; + permutations(index + 1, used); + used[i] = '0'; + } + i++; + } } -// Função auxiliar para trocar dois caracteres (usada na ordenação) -void ft_swap(char *a, char *b) +char *populate_used() { - char temp = *a; - *a = *b; - *b = temp; + char *ret = (char *) calloc (length + 1, sizeof(char)); + int i = 0; + while (i < length) + ret[i++] = '0'; + return (ret); } -// 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 main(int ac, char **av) { - 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++; - } -} - -// 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) -{ - // Caso base: Se todas as posições foram preenchidas (k == n), - // análogo a `if (col == n)` no N-Queens. - if (k == n) - { - print_solution(current_perm); - return; - } - - // Tenta colocar cada caractere da string original na posição 'k' atual - int i = 0; - while (i < n) - { - // 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++; - } -} - -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); + if (ac != 2) + return (1); + set = av[1]; + length = ft_strlen(av[1]); + char *used = populate_used(); + permutation = (char *) malloc(sizeof(char) * (length + 1)); + permutations(0, used); + free(used); + free(permutation); + return (0); } \ No newline at end of file diff --git a/level-2/powerset/powerset_clean.c b/level-2/powerset/powerset_clean.c index 31498d8..a691a19 100644 --- a/level-2/powerset/powerset_clean.c +++ b/level-2/powerset/powerset_clean.c @@ -1,68 +1,71 @@ #include #include -void print_subset(int *subset, int size) -{ - int i; +int target; +int length; +int *set; - i = 0; - while (i < size) - { - printf("%d", subset[i]); - if (i < size - 1) - printf(" "); - i++; - } - printf("\n"); +void populate_array(int ac, char **av) +{ + int i = 0; + int j = 2; + while(j < ac) + { + set[i] = atoi(av[j]); + i++; + j++; + } } -void find_subsets(int target, int *set, int set_size, int index, int *current_path, int path_len) +void print_set(int *used) { - 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 i = 0; + int is_first = 1; + while(i < length) + { + if (used[i] == 1) + { + if (is_first) + { + fprintf(stdout, "%i", set[i]); + is_first = 0; + } + else + fprintf(stdout, " %i", set[i]); + } + i++; + } + printf("\n"); } -int main(int argc, char **argv) +void powerset(int index, int current_sum, int *used) { - int target; - int *numbers; - int *path; - int size; - int i; + if (index == length) + { + if (current_sum == target) + print_set(used); + return ; + } - if (argc < 2) - return (0); + powerset(index + 1, current_sum, used); + used[index] = 1; + powerset(index + 1, current_sum + set[index], used); + used[index] = 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); +int main(int ac, char **av) +{ + if (ac < 2) + return (1); + + length = ac -2; + target = atoi(av[1]); + set = (int *) malloc (sizeof(int) * length); + int *used = (int *) calloc (length, sizeof(int)); + populate_array(ac, av); + powerset(0, 0, used); + free(set); + free(used); + return (0); + } \ No newline at end of file