Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added delim #8

Merged
merged 13 commits into from
Apr 16, 2024
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/valgrind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ jobs:
- name: valgrind check
run: |
make DEBUG=1
valgrind --show-leak-kinds=all -s --leak-check=full --track-origins=yes ./seqperm --reverse full --upper full --leet full --start 1 --end 5 --only_transformations n --last 2024,001,1,355 --connectors .,- hi how are you fine 1>/dev/null
valgrind --show-leak-kinds=all -s --leak-check=full --track-origins=yes ./seqperm --reverse full --upper full --leet full --start 1 --end 5 --only_transformations y --last 2024,001,1,355 --connectors .,- hi how are you fine 1>/dev/null
valgrind --show-leak-kinds=all -s --leak-check=full --track-origins=yes ./seqperm --reverse full --upper full --leet full --start 1 --end 5 --only_transformations n --last 2024,001,1,355 --connectors .,- hi how ar,e you fi,ne 1>/dev/null
valgrind --show-leak-kinds=all -s --leak-check=full --track-origins=yes ./seqperm --reverse full --upper full --leet full --start 1 --end 5 --only_transformations y --last 2024,001,1,355 --connectors .,- hi how ar,e you fi,ne 1>/dev/null
valgrind --show-leak-kinds=all -s --leak-check=full --track-origins=yes ./seqperm --start 1 --end 10 a b c d e f g h i l 1>/dev/null
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
if one or more modifiers are setted, print only the transformations created with all modifiers instead of printing each one
```
```
All the words with the delimiter "," (ex. fish,es) will be considered as shortened permutation, in this case only short string or full string will be in a single permutation.
So, if you have in input fishes and fish and max word = 2, the permutation fishesfish will be created.
Instead, if "," is used, and in input you have fish,es the permutation fishesfish will not be created, but you'll have (for example) fishOTHERWORD fishesOTHERWORD
```
```
words/chars go after parameters separeted by space
```
## Sample Usage
Expand All @@ -30,5 +35,7 @@ We dont't want any uppercase first character.
```
./seqperm --upper n --start 3 --end 5 --last 0,1 --connectors ,. a b c d e f g h i l m
```
## TO DO
Implement ```--delim wo,rd``` for considering a word a possible shortener permutation, in a single permutation will be only the full word or its delim wo. Multiple handling of , is a plus
## Complexity as number of permutation generated
$$
(\sum_{k=start}^{end}{\binom{words}{k} \cdot k!}) \times (connectors + 1) \times (upper + 1) \times (last + 1) \times (leet + 1) \times (reverse + 1)
$$
139 changes: 110 additions & 29 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
Expand All @@ -15,35 +16,31 @@ static char **dict;
static size_t word_size;
static Queue_t **all_queues = NULL;
static char **connectors = NULL;
static unsigned short ***delim_bins = NULL;
static char leet_map[128] = {0x0};
static char **last = NULL;
static size_t connectors_size = 0;
static size_t last_size = 0;
static const char *connector_placeholder = "|";
static modifiers_t bool_modifiers = {0x0};

unsigned **binomial_coefficient(size_t n, size_t k)
void gen_bin_to_arr(unsigned short *arr, size_t size, size_t idx, size_t max, size_t cur, size_t min, unsigned short ***out, size_t *out_size)
{
unsigned **C = (unsigned **)calloc(n + 1, sizeof(unsigned *));
for (size_t i = 0; i <= n; i++)
if (idx == size)
{
C[i] = (unsigned *)calloc(k + 1, sizeof(unsigned));
unsigned short *copy = (unsigned short *)malloc(sizeof(unsigned short) * size);
memcpy(copy, arr, sizeof(unsigned short) * size);
out[size][*out_size] = copy;
*out_size = *out_size + 1;
return;
}
for (size_t i = 0; i <= n; i++)
arr[idx] = 0;
gen_bin_to_arr(arr, size, idx + 1, max, cur, min, out, out_size);
if (cur < max)
{
for (size_t j = 0; j <= k && j <= i; j++)
{
if (j == 0 || j == i)
{
C[i][j] = 1;
}
else
{
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
}
arr[idx] = 1;
gen_bin_to_arr(arr, size, idx + 1, max, cur + 1, min, out, out_size);
}
return C;
}

void free_inputs_optind(void)
Expand Down Expand Up @@ -111,7 +108,7 @@ inline void print_out(char **arr, size_t size)
char finalString[BUFF] = {0x0};
char *all_strings[BUFF] = {0x0};
size_t run_len = 0, strings_len = 0;
size_t lengths[size];
size_t lengths[BUFF];
size_t saved_len = 0;
size_t reverse_make_sense = false;
for (size_t i = 0; i < size; i++)
Expand Down Expand Up @@ -327,17 +324,78 @@ void gen_bin_perms(unsigned short *arr, size_t size, size_t idx, size_t max, siz
{
if (cur >= min && cur <= max)
{
char **auxPerm = (char **)malloc(sizeof(char *) * cur);
size_t pointer = 0;
char **auxPerm = (char **)calloc(cur, sizeof(char *));
size_t pointer = 0, delim = 0;
size_t idx_delim[word_size];
for (size_t j = 0; j < word_size; j++)
{
if (arr[j] == 1)
{
auxPerm[pointer] = (char *)calloc(strlen(dict[j]) + 1, sizeof(char));
memccpy(auxPerm[pointer++], dict[j], '\0', strlen(dict[j]));
char *p = strchr(dict[j], ',');
if (p == NULL)
{
auxPerm[pointer] = (char *)calloc(strlen(dict[j]) + 1, sizeof(char));
memccpy(auxPerm[pointer++], dict[j], '\0', strlen(dict[j]));
}
else
{
idx_delim[delim++] = j;
}
}
}
if (delim)
{
delim_t delim_words[delim];
memset(&delim_words, 0x0, sizeof(delim_t) * delim);
size_t delim_size = 0;
for (size_t d = 0; d < delim; d++)
{
char *pp = strdup(dict[idx_delim[d]]);
char *p = strtok(pp, ",");
delim_words[delim_size].p1 = strdup(p);
p = strtok(NULL, ",");
char *copy = (char *)calloc(strlen(delim_words[delim_size].p1) + strlen(p) + 1, sizeof(char));
copy = strcat(copy, delim_words[delim_size].p1);
copy = strcat(copy, p);
delim_words[delim_size++].p2 = copy;
free(pp);
}
size_t n_bin_delim = (size_t)(1 << delim);
unsigned short **bins = delim_bins[delim];
for (size_t i = 0; i < n_bin_delim; i++)
{
char **full_dict = (char **)malloc(sizeof(char *) * cur);
for (size_t n = 0; n < pointer; n++)
{
full_dict[n] = strdup(auxPerm[n]);
}
size_t size_dict = pointer;
unsigned short *x = bins[i];
for (size_t j = 0; j < delim; j++)
{
delim_t *delim_word = &delim_words[j];
full_dict[size_dict++] = x[j] ? strdup(delim_word->p2) : strdup(delim_word->p1);
}
push_queue(all_queues[cur - min], full_dict, cur);
}
for (size_t i = 0; i < delim; i++)
{
free(delim_words[i].p1);
free(delim_words[i].p2);
}
for (size_t i = 0; i < cur; i++)
{
if (auxPerm[i] != NULL)
{
free(auxPerm[i]);
}
}
free(auxPerm);
}
else
{
push_queue(all_queues[cur - min], auxPerm, pointer);
}
push_queue(all_queues[cur - min], auxPerm, cur);
}
return;
}
Expand Down Expand Up @@ -473,16 +531,30 @@ int main(int argc, char **argv)
queue_n = max_len - min_len + 1;
thread_n = (size_t)(max_len * (max_len + 1)) / 2;
all_queues = (Queue_t **)malloc(sizeof(Queue_t *) * queue_n);
unsigned **C = binomial_coefficient(word_size, max_len);
for (size_t i = 0; i < queue_n; i++)
// find n_delim
size_t n_delim = 0;
size_t optind_copy = optind;
for (size_t i = 0; i < word_size; i++)
{
all_queues[i] = init_queue(C[word_size][min_len + i]);
if (strchr(argv[optind_copy++], ',') != NULL)
{
n_delim++;
}
}
for (size_t i = 0; i < word_size + 1; i++)
unsigned short ***bin_delim = (unsigned short ***)malloc(sizeof(unsigned short **) * (n_delim + 1));
for (size_t i = 1; i < n_delim + 1; i++)
{
bin_delim[i] = (unsigned short **)malloc(sizeof(unsigned short *) * (1 << i));
unsigned short *bin = (unsigned short *)calloc(i, sizeof(unsigned short));
size_t bd_size = 0;
gen_bin_to_arr(bin, i, 0, i, 0, 0, bin_delim, &bd_size);
free(bin);
}
delim_bins = bin_delim;
for (size_t i = 0; i < queue_n; i++)
{
free(C[i]);
all_queues[i] = default_init_queue(); // need to calculate n of elements given min max delim size ?
}
free(C);
char **input_words = (char **)malloc(sizeof(char *) * word_size);
for (size_t i = 0; i < word_size; i++)
{
Expand Down Expand Up @@ -514,6 +586,15 @@ int main(int argc, char **argv)
{
pthread_join(tworker[i], NULL);
}
for (size_t i = 1; i < n_delim + 1; i++)
{
for (size_t j = 0; j < (1 << i); j++)
{
free(bin_delim[i][j]);
}
free(bin_delim[i]);
}
free(bin_delim);
for (size_t i = 0; i < queue_n; i++)
{
free_queue(all_queues[i]);
Expand Down
7 changes: 7 additions & 0 deletions main.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ typedef struct bool_t
uint8_t __padding : 1;
} modifiers_t;

typedef struct delim_t
{
char *p1;
char *p2;
} delim_t;

void print_out(char **arr, size_t size);
void print_f_maiusc(char **arr, char *string);
void print_number(char **arr, char *finalString, size_t run_len);
Expand All @@ -46,6 +52,7 @@ void seq_perm(char **arr, size_t size);
void *thread_perm(void *in);
void gen_bin_perms(unsigned short *arr, size_t size, size_t idx, size_t max, size_t cur, size_t min);
size_t add_string(char *buff[BUFF], size_t idx, char *to_push, size_t to_push_len);
void gen_bin_to_arr(unsigned short *arr, size_t size, size_t idx, size_t max, size_t cur, size_t min, unsigned short ***out, size_t *out_size);
unsigned **binomial_coefficient(size_t n, size_t k);
void free_inputs_optind(void);
void exit_usage(char *plus);
Expand Down
19 changes: 18 additions & 1 deletion queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
#include <stdlib.h>
#include <string.h>

Queue_t *default_init_queue()
{
return init_queue(QUEUE_LEN);
}

Queue_t *init_queue(size_t size)
{
Queue_t *Q = (Queue_t *)malloc(sizeof(Queue_t));
Expand All @@ -13,7 +18,7 @@ Queue_t *init_queue(size_t size)
perror("POINTER_QUEUE_INIT_FAIL");
exit(EXIT_FAILURE);
}
Q->words = (input_t **)malloc(sizeof(input_t *) * size);
Q->words = (input_t **)calloc(size, sizeof(input_t *));
if (Q->words == NULL)
{
perror("BUCKET_QUEUE_INIT_FAIL");
Expand All @@ -30,6 +35,10 @@ void push_queue(Queue_t *Q, char **aux, size_t len)
input_t *inQueue = (input_t *)malloc(sizeof(input_t));
inQueue->aux = aux;
inQueue->len = len;
if (Q->tail >= Q->maxsize)
{
resize(Q);
}
Q->words[Q->tail++] = inQueue;
}

Expand All @@ -45,3 +54,11 @@ void free_queue(Queue_t *Q)
{
free(Q->words);
}

void resize(Queue_t *Q)
{
size_t old_size = Q->maxsize;
Q->maxsize *= 2;
Q->words = (input_t **)realloc(Q->words, sizeof(input_t *) * Q->maxsize);
memset(Q->words + old_size, 0x0, sizeof(input_t *) * (Q->maxsize - old_size));
}
3 changes: 3 additions & 0 deletions queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdatomic.h>
#define QUEUE_LEN 128

typedef struct input_aux_perm {
char **aux;
Expand All @@ -21,4 +22,6 @@ Queue_t *init_queue(size_t size);
void push_queue(Queue_t *Q, char **aux, size_t len);
input_t *pop_queue(Queue_t *Q);
void free_queue(Queue_t *Q);
void resize(Queue_t *Q);
Queue_t *default_init_queue();
#endif