From 834f854fd9ead2f8085f471dcaeb85004833b0c1 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Mon, 4 Nov 2019 11:47:14 +0100 Subject: [PATCH] Added working solution for bexp --- array/array.c | 60 +++++++++++++++++++++++++++++ array/array.h | 19 ++++++++++ bexp/bexp.c | 27 +++++++------ bexp/bexp_calculator.c | 77 +++++++++++++++++++++++++++----------- func_pointers/collection.c | 51 +++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 34 deletions(-) create mode 100644 array/array.c create mode 100644 array/array.h create mode 100644 func_pointers/collection.c diff --git a/array/array.c b/array/array.c new file mode 100644 index 0000000..f46d96c --- /dev/null +++ b/array/array.c @@ -0,0 +1,60 @@ +#include "array.h" + +struct var_int_array { + int* data; + size_t size; + size_t capacity; +}; + +varray* var_int_array_new() { + varray* a = malloc(sizeof(struct var_int_array)); + if (a) { + a->size = 0; + a->capacity = 10; + a->data = malloc(sizeof(int) * a->capacity); + + if (!a->data) { + free(a); + } + } + return a; +} + +void var_int_array_destroy(varray* v) { + free(v->data); + free(v); +} + +size_t var_int_array_size(const varray* v) { + return v->size; +} + +int var_int_array_append(varray* v, int value) { + if (v->size == v->capacity) { + size_t new_cap = v->capacity * 2; + int* new = realloc(v->data, new_cap); + + if (!new) { + return 0; + } + + v->data = new; + v->capacity = new_cap; + } + + v->data[v->size++] = value; + return 1; +} + +int var_int_array_pop(varray* v) { + return v->data[--v->size]; +} + +int var_int_array_get(const varray* v, size_t idx) { + return v->data[idx]; +} + +void var_int_array_put(varray* v, size_t idx, int val) { + v->data[idx] = val; +} + diff --git a/array/array.h b/array/array.h new file mode 100644 index 0000000..743fa1b --- /dev/null +++ b/array/array.h @@ -0,0 +1,19 @@ +#ifndef ARRAY_H_INCLUDED +#define ARRAY_H_INCLUDED +#include + +struct var_int_array; +typedef struct var_int_array varray; + +varray* var_int_array_new(); +void var_int_array_destroy(varray*); + +size_t var_int_array_size(const varray*); + +int var_int_array_append(varray*, int value); +int var_int_array_pop(varray*); + +int var_int_array_get(const varray*, size_t idx); +void var_int_array_put(varray*, size_t idx, int val); + +#endif diff --git a/bexp/bexp.c b/bexp/bexp.c index 7588842..c64296f 100644 --- a/bexp/bexp.c +++ b/bexp/bexp.c @@ -55,19 +55,19 @@ int bexp_loop(value* result, const expression* ex, compute_func compute) { } int compute_and(char* r, int a, int b, int* _) { *r += a && b; return 0; } -int compute_or(char* r, int a, int b, int* _) { *r += a && b; return 0; } -int compute_xor(char* r, int a, int b, int* _) { *r += a && b; return 0; } +int compute_or(char* r, int a, int b, int* _) { *r += a || b; return 0; } +int compute_xor(char* r, int a, int b, int* _) { *r += a ^ b; return 0; } int compute_gt(char* r, int a, int b, int* _) { *r += a > b; return a != b; } int compute_lt(char* r, int a, int b, int* _) { *r += a < b; return a != b; } int compute_plus(char* r, int a, int b, int* c) { *r += a ^ b ^ *c; - *c = a && b || ((a ^ b) && *c); + *c = (a && b) || ((a ^ b) && *c); return 0; } -int compute_compl(char* r, int a, int _, int* __) { *r = !a; return 0; } -int compute_not(char* r, int a, int _, int* __) { *r = !a; return a; } +int compute_compl(char* r, int a, int _, int* __) { *r += !a; return 0; } +int compute_not(char* r, int a, int _, int* __) { *r += !a; return a; } compute_func bexp_compute(const operator_t op) { switch (op) { @@ -95,15 +95,18 @@ int bexp_length(const expression* ex) { case PLUS: { const int l1 = value_length(&ex->value1); const int l2 = value_length(&ex->value2); + const int max = l1 > l2 ? l1 : l2; - // handle overflow - if (l1 == l2 && l1 > 0 && - *(ex->value1.end - 1) == '1' && - *(ex->value2.end - 1) == '1') { - return l1 + 1; - } else { - return l1 > l2 ? l1 : l2; + char tmp[max + 1]; + tmp[max] = '0'; + + value result = { tmp, tmp + max + 1 }; + + if (!bexp_loop(&result, ex, compute_plus)) { + return -1; } + + return tmp[max] == '1' ? max + 1 : max; } case GREATER_THAN: diff --git a/bexp/bexp_calculator.c b/bexp/bexp_calculator.c index 3312671..d7b3804 100644 --- a/bexp/bexp_calculator.c +++ b/bexp/bexp_calculator.c @@ -9,21 +9,31 @@ typedef struct stack { value first; struct stack* next; char container[]; -} stack_t; +} expr_stack_t; -stack_t* tos = NULL; +static void read_word(); +static void read_value(); +static void read_command(); +static void discard(); +static int ensure(char* str); +static void print_value(const value* val); +static void read_command(); -void read_value(); -void read_command(); -void discard(); +static expr_stack_t* tos = NULL; + +int main() { + while(!feof(stdin)) { + read_word(); + } +} void discard() { - fprintf(stderr, "Value is malformed. Discarding until space...\n"); - while(isspace(getchar())); + fprintf(stderr, "Input malformed. Discarding until space...\n"); + while(!isspace(getchar())); return; } -int read_word() { +void read_word() { char c; while (isspace(c = getchar())); ungetc(c, stdin); @@ -36,7 +46,7 @@ int read_word() { void read_value() { int str_size = 10; - stack_t* new = malloc(sizeof(stack_t) + str_size * sizeof(char)); + expr_stack_t* new = malloc(sizeof(expr_stack_t) + str_size * sizeof(char)); if (!new) { perror("Cannot allocate new stack element"); return; @@ -44,9 +54,9 @@ void read_value() { new->next = tos; int count = 0; - char c; + int c; while(!isspace(c = getchar())) { - if (c != '0' || c != '1') { + if (c != '0' && c != '1') { free(new); discard(); return; @@ -56,7 +66,7 @@ void read_value() { if (str_size == count) { str_size *= 2; - new = realloc(new, sizeof(stack_t) + str_size * sizeof(char)); + new = realloc(new, sizeof(expr_stack_t) + str_size * sizeof(char)); if (!new) { perror("Cannot allocate new stack element"); free(new); @@ -65,13 +75,25 @@ void read_value() { } } + // reverse the string in container to match least to most significant order + // in bexp + char* i = new->container; + char* j = new->container + count - 1; + while (i < j) { + char tmp = *i; + *i = *j; + *j = tmp; + i++; + j--; + } + new->first.begin = new->container; new->first.end = new->container + count; tos = new; } int ensure(char* str) { - while (str) { + while (*str) { if (tolower(getchar()) != *str) { return 0; } @@ -81,8 +103,8 @@ int ensure(char* str) { } void print_value(const value* val) { - char* v = val->begin; - while (v != val->end) putchar(*(v++)); + char* v = val->end - 1; + while (v >= val->begin) putchar(*(v--)); putchar('\n'); } @@ -118,7 +140,7 @@ void read_command() { printf("empty\n"); } else { print_value(&(tos->first)); - stack_t* t = tos; + expr_stack_t* t = tos; tos = tos->next; free(t); } @@ -134,18 +156,29 @@ void read_command() { return; } - expression_t ex = { op, tos->value, binary ? tos->next->value : NULL }; + const static value dummy = { NULL, NULL }; + expression ex = { op, tos->first, binary ? tos->next->first : dummy }; int length = bexp_length(&ex); - char* result = malloc(sizeof(stack_t) + sizeof(char) * length); - if (!result) { + expr_stack_t* new_tos = malloc(sizeof(expr_stack_t) + sizeof(char) * length); + if (!new_tos) { perror("Cannot allocate space for result"); return; } - value v_result = { result, result + length }; + new_tos->first.begin = new_tos->container; + new_tos->first.end = new_tos->container + length; - bexp_evaluate(&v_result, &ex); - stack_t + bexp_evaluate(&new_tos->first, &ex); + expr_stack_t* new_next = tos->next; + free(tos); + tos = new_next; + if (binary) { + new_next = tos->next; + free(tos); + tos = new_next; + } + new_tos->next = tos; + tos = new_tos; } diff --git a/func_pointers/collection.c b/func_pointers/collection.c new file mode 100644 index 0000000..bfc8534 --- /dev/null +++ b/func_pointers/collection.c @@ -0,0 +1,51 @@ +#include +#include + +struct collection { + int* values; + size_t size; + size_t capacity; +}; + +void collection_print(struct collection * c, void(*f)(int)) { + for (size_t i = 0; i < c->size; i++) { + (*f)(c->values[i]); + } +} + +struct collection * new_random_collection() { + struct collection* new = malloc(sizeof(struct collection)); + if (!new) { + return NULL; + } + + new->size = 50; + new->capacity = 100; + new->values = malloc(new->capacity * sizeof(int)); + if (!new->values) { + free(new); + return NULL; + } + + for (size_t i = 0; i < new->size; i++) { + new->values[i] = rand(); + } + + return new; +} + +void collection_delete(struct collection *c) { + free(c->values); + free(c); +} + +void pretty_print(int b) { + printf("%d, ", b); +} + +int main() { + struct collection* c; + c = new_random_collection(); + collection_print(c, pretty_print); + collection_delete(c); +}