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_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_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_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_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_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) {
|
int compute_plus(char* r, int a, int b, int* c) {
|
||||||
*r += a ^ b ^ *c;
|
*r += a ^ b ^ *c;
|
||||||
*c = a && b || ((a ^ b) && *c);
|
*c = (a && b) || ((a ^ b) && *c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int compute_compl(char* r, int a, int _, int* __) { *r = !a; 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_not(char* r, int a, int _, int* __) { *r += !a; return a; }
|
||||||
|
|
||||||
compute_func bexp_compute(const operator_t op) {
|
compute_func bexp_compute(const operator_t op) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -95,15 +95,18 @@ int bexp_length(const expression* ex) {
|
||||||
case PLUS: {
|
case PLUS: {
|
||||||
const int l1 = value_length(&ex->value1);
|
const int l1 = value_length(&ex->value1);
|
||||||
const int l2 = value_length(&ex->value2);
|
const int l2 = value_length(&ex->value2);
|
||||||
|
const int max = l1 > l2 ? l1 : l2;
|
||||||
|
|
||||||
// handle overflow
|
char tmp[max + 1];
|
||||||
if (l1 == l2 && l1 > 0 &&
|
tmp[max] = '0';
|
||||||
*(ex->value1.end - 1) == '1' &&
|
|
||||||
*(ex->value2.end - 1) == '1') {
|
value result = { tmp, tmp + max + 1 };
|
||||||
return l1 + 1;
|
|
||||||
} else {
|
if (!bexp_loop(&result, ex, compute_plus)) {
|
||||||
return l1 > l2 ? l1 : l2;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return tmp[max] == '1' ? max + 1 : max;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GREATER_THAN:
|
case GREATER_THAN:
|
||||||
|
|
|
@ -9,21 +9,31 @@ typedef struct stack {
|
||||||
value first;
|
value first;
|
||||||
struct stack* next;
|
struct stack* next;
|
||||||
char container[];
|
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();
|
static expr_stack_t* tos = NULL;
|
||||||
void read_command();
|
|
||||||
void discard();
|
int main() {
|
||||||
|
while(!feof(stdin)) {
|
||||||
|
read_word();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void discard() {
|
void discard() {
|
||||||
fprintf(stderr, "Value is malformed. Discarding until space...\n");
|
fprintf(stderr, "Input malformed. Discarding until space...\n");
|
||||||
while(isspace(getchar()));
|
while(!isspace(getchar()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_word() {
|
void read_word() {
|
||||||
char c;
|
char c;
|
||||||
while (isspace(c = getchar()));
|
while (isspace(c = getchar()));
|
||||||
ungetc(c, stdin);
|
ungetc(c, stdin);
|
||||||
|
@ -36,7 +46,7 @@ int read_word() {
|
||||||
|
|
||||||
void read_value() {
|
void read_value() {
|
||||||
int str_size = 10;
|
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) {
|
if (!new) {
|
||||||
perror("Cannot allocate new stack element");
|
perror("Cannot allocate new stack element");
|
||||||
return;
|
return;
|
||||||
|
@ -44,9 +54,9 @@ void read_value() {
|
||||||
new->next = tos;
|
new->next = tos;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
char c;
|
int c;
|
||||||
while(!isspace(c = getchar())) {
|
while(!isspace(c = getchar())) {
|
||||||
if (c != '0' || c != '1') {
|
if (c != '0' && c != '1') {
|
||||||
free(new);
|
free(new);
|
||||||
discard();
|
discard();
|
||||||
return;
|
return;
|
||||||
|
@ -56,7 +66,7 @@ void read_value() {
|
||||||
|
|
||||||
if (str_size == count) {
|
if (str_size == count) {
|
||||||
str_size *= 2;
|
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) {
|
if (!new) {
|
||||||
perror("Cannot allocate new stack element");
|
perror("Cannot allocate new stack element");
|
||||||
free(new);
|
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.begin = new->container;
|
||||||
new->first.end = new->container + count;
|
new->first.end = new->container + count;
|
||||||
tos = new;
|
tos = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ensure(char* str) {
|
int ensure(char* str) {
|
||||||
while (str) {
|
while (*str) {
|
||||||
if (tolower(getchar()) != *str) {
|
if (tolower(getchar()) != *str) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -81,8 +103,8 @@ int ensure(char* str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_value(const value* val) {
|
void print_value(const value* val) {
|
||||||
char* v = val->begin;
|
char* v = val->end - 1;
|
||||||
while (v != val->end) putchar(*(v++));
|
while (v >= val->begin) putchar(*(v--));
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +140,7 @@ void read_command() {
|
||||||
printf("empty\n");
|
printf("empty\n");
|
||||||
} else {
|
} else {
|
||||||
print_value(&(tos->first));
|
print_value(&(tos->first));
|
||||||
stack_t* t = tos;
|
expr_stack_t* t = tos;
|
||||||
tos = tos->next;
|
tos = tos->next;
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
@ -134,18 +156,29 @@ void read_command() {
|
||||||
return;
|
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);
|
int length = bexp_length(&ex);
|
||||||
|
|
||||||
char* result = malloc(sizeof(stack_t) + sizeof(char) * length);
|
expr_stack_t* new_tos = malloc(sizeof(expr_stack_t) + sizeof(char) * length);
|
||||||
if (!result) {
|
if (!new_tos) {
|
||||||
perror("Cannot allocate space for result");
|
perror("Cannot allocate space for result");
|
||||||
return;
|
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);
|
bexp_evaluate(&new_tos->first, &ex);
|
||||||
stack_t
|
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