Added working solution for bexp

This commit is contained in:
Claudio Maggioni 2019-11-04 11:47:14 +01:00
parent b83a7d9378
commit 834f854fd9
5 changed files with 200 additions and 34 deletions

60
array/array.c Normal file
View file

@ -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;
}

19
array/array.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef ARRAY_H_INCLUDED
#define ARRAY_H_INCLUDED
#include <stdlib.h>
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

View file

@ -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:

View file

@ -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 };
bexp_evaluate(&v_result, &ex);
stack_t
new_tos->first.begin = new_tos->container;
new_tos->first.end = new_tos->container + length;
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;
}

View file

@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
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);
}