Added working solution for bexp
This commit is contained in:
parent
b83a7d9378
commit
834f854fd9
5 changed files with 200 additions and 34 deletions
60
array/array.c
Normal file
60
array/array.c
Normal 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
19
array/array.h
Normal 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
|
27
bexp/bexp.c
27
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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
51
func_pointers/collection.c
Normal file
51
func_pointers/collection.c
Normal 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);
|
||||
}
|
Reference in a new issue