From 0b6c839b4df50bd76d7cc341c0e650edbcfe5e77 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Wed, 20 Jan 2021 16:22:59 +0100 Subject: [PATCH] initial version --- .gitignore | 9 +++ Makefile | 28 +++++++ eval.c | 62 ++++++++++++++++ lceb.c | 68 +++++++++++++++++ lceb.h | 52 +++++++++++++ oper.c | 58 +++++++++++++++ stack.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tree.c | 45 ++++++++++++ 8 files changed, 534 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 eval.c create mode 100644 lceb.c create mode 100644 lceb.h create mode 100644 oper.c create mode 100644 stack.c create mode 100644 tree.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b06518 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +core +com* +ex1* +*.o +perm* +oper +tree +lceb +gmon.out \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e8895fb --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +SHELL := /bin/bash +#CFLAGS := -w -O3 +CFLAGS := -w -g -pg -DDEBUG +TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n" +export PATH := .:$(PATH) + +TARGETS=lceb tree oper stack eval +INCLUDES=lceb.h +OBJS=$(TARGETS:=.o) + +.PHONY: all clean stack eval + +all: $(TARGETS) + +lceb: $(OBJS) + +tree: tree.c lceb.h + $(CC) $(CFLAGS) -DSTANDALONE -o $@ $? +oper: oper.c lceb.h + $(CC) $(CFLAGS) -DSTANDALONE -o $@ $? + +ex2: ex2-c + @$(TIME) ex2-c < $(INPUT) + +%.o: %.c $(INCLUDES) + +clean: + rm -f $(TARGETS) $(OBJS) core diff --git a/eval.c b/eval.c new file mode 100644 index 0000000..7dbb53f --- /dev/null +++ b/eval.c @@ -0,0 +1,62 @@ +#include +#include "lceb.h" + +int eval_cell(pos) + STACKELT *pos; +{ + STACKELT *prev=pos-1; + int curop=pos->curop, nop=pos->nop; + int val1, val2; + char op; + int res; + + while (curopop[curop]; + val2=pos->val; + res=-1; + printf("eval_cell(%c, %d)\n", op, val2); + while ((val1=prev->val) == -1) + prev--; + switch (op) { + case Nop: + case End: + return val2; + break; + case Add: + res=val1+val2; + break; + case Mul: + res=val1*val2; + break; + case Sub: + if (val1 > val2) + res=val1-val2; + break; + case Div: + if (val1 > val2 && (val1 % val2 == 0)) + res=val1/val2; + break; + } + curop++; + if (res==-1) + break; + pos->val=res; + printf("\t--> eval=%d\n", res); + } + return res; +} + +int eval_stack(stack) + STACK *stack; +{ + int pos, last=stack->last, res; + STACKELT *pstack=stack->stack; + + printf("+++++ eval_stack: addr=%p\n", pstack); + for (pos=1; poslast, pstack+pos); + res=eval_cell(stack->stack+pos); + //printf(" -> val(%d)=%d\n", pos, res); + } + return res; +} diff --git a/lceb.c b/lceb.c new file mode 100644 index 0000000..a9bcd32 --- /dev/null +++ b/lceb.c @@ -0,0 +1,68 @@ +/* compte-est-bon.c - should one day solve this game... + * + * $ make compte-est-bon + * $ ./compte-est-bon target n1 n2 [...n6] + * + * At least 2 "n" are mandatory, and no more than 6 are allowed. + * + */ + +#include +#include +#include +#include +#include +#include "lceb.h" + + + +int main(ac, av) + int ac; + char **av; +{ + unsigned target; + STACK *stack; + int i, stacksize, val, res; + char *ops="+-*/", *opscomb; + int len_ops=strlen(ops), ncombs, nops; + + if (ac < 4 || ac > 2+MAXINPUT) { + fprintf(stderr, "usage: %s target n1 n2 [...n%d]\n", *av, MAXINPUT); + exit(1); + } + target=atoi(av[1]); + stacksize=2*(ac-2)-1; + nops=ac-2-1; + ncombs=ncombinations(len_ops, nops); + printf("target=%d\nstacksize=%d\nops_comb=%d\n", target, stacksize, ncombs); + printf("len_ops=%d\nnops=%d\nops_comb=%d\n", len_ops, nops, ncombs); + stack=new_stack(stacksize, "Main Stack"); + for (i=2; istack, 0, stack->last-1); + print_stack(stack, 1); + + i=1; + do { + printf("permutation %2d: ", i++); + print_stack(stack, 0); + } while (permute_stack(stack->stack, stack->last)); + + printf("operators combinations (%d) = ", ncombs); + for (i=0; i +#include +#include "lceb.h" + +unsigned ncombinations(nops, len) + int nops, len; +{ + int result = 1; + while(len > 0){ + if(len & 1) + result *= nops; + nops *= nops; + len >>=1; + } + return result; +} + +char *combination(ops, len, n) + char *ops; /* string to combine */ + int len; /* len of result */ + int n; /* iteration # */ +{ + static char *res=NULL; + static int len_ops; + int i; + + if (!res) { // 1st call + len_ops=strlen(ops); + res=malloc(len * sizeof(char) + 1); + } + for(i=0; i +#include +#include +#include "lceb.h" + +void print_stack(stack, details) + STACK *stack; + int details; +{ + int i; + + if (details) { + printf("Stack [%s] dump: %d/%d used\n", stack->name, stack->last, stack->size); + printf("\tValue: %4d\n", stack->eval); + for (i=0; ilast; ++i) + printf("\t%02d: Op=%s Val=%4d\n", + i, (char *)stack->stack[i].op, stack->stack[i].val); + } else { + printf("Stack [%s] : ", stack->name); + for (i=0; ilast; ++i) { + printf("%d[%s] ", stack->stack[i].val, (char *)stack->stack[i].op); + } + printf("\n"); + } +} + +STACK *new_stack(size, name) + int size; /* 0 if empty */ + char *name; +{ + STACK *stack; + STACKELT *pelt; + int i; + + stack=malloc(sizeof (STACK)); + stack->stack=NULL; + stack->size=0; + stack->last=0; + stack->eval=0; + strncpy(stack->name, name? name: "No name", sizeof(stack->name)); + if (size) { + pelt=malloc(size*sizeof(STACKELT)); + stack->size=size; + stack->stack=pelt; + for (i=0; inop=0; + (pelt+i)->curop=0; + (pelt+i)->op[0]=End; + (pelt+i)->val=-1; + (pelt+i)->next=i+1; + (pelt+i+1)->prev=i; + } + (pelt+i-1)->next=-1; + } + return stack; +} + +STACKELT *push_stack(stack, op, val) + STACK *stack; + OPER op; + int val; +{ + int pos=stack->last; + int size=stack->size; + STACKELT *pelt=stack->stack+stack->last; + + if (pos >= size) { + fprintf(stderr, "stack overflow: size=%d last=%d\n", size, pos); + return NULL; + } + pelt->nop=0; + pelt->curop=0; + //pelt->op[0]=op; + pelt->val=val; + stack->last++; + return pelt; +} + +STACKELT *pop_stack(stack) + STACK *stack; +{ + int pos=stack->last+1; + int size=stack->size; + STACKELT *pelt=stack->stack+stack->last; + + if (pos==0) { + fprintf(stderr, "stack empty: size=%d last=%d\n", size, pos); + return NULL; + } + stack->last--; + return pelt; +} + +STACK *dup_stack(stack, name) + STACK *stack; + char *name; +{ + STACK *new; + STACKELT *src=stack->stack, *dst; + int size=stack->size, last=stack->last, i; + + new=new_stack(size, name); + dst=new->stack; + for (i=0; inop=src->nop; + dst->curop=src->curop; + dst->val=src->val; + memcpy(dst->op, src->op, sizeof(src->op)); + } + stack->last++; + return new; +} + +void swap(elts, i, j) + STACKELT *elts; + int i, j; +{ + STACKELT tmp=elts[i]; + elts[i] = elts[j]; + elts[j] = tmp; +} + +int permute_stack(array, n) + STACKELT *array; + int n; +{ + int i, j, start, end; + + for(i=n-2; i>-1; i--) { + if(array[i+1].val > array[i].val) { + for(j=n-1; j>i; j--){ + if(array[j].val > array[i].val){ + // swap + swap(array, i, j); + // reverse + for (start=i+1, end=n-1; start < end; ++start, --end) + swap(array, start, end); + return 1; + } + } + } + } + return 0; +} + + +void mergesort_stack(array, left, right) + STACKELT *array; + int left, right; +{ + int mid = (left+right)/2; + int pos=0, l=left, r=mid+1, i; + STACKELT tmp[right-left+1]; + + if(left < right) { + mergesort_stack(array, left, mid); + mergesort_stack(array, mid+1,right); + while (l <= mid && r <= right) { + if (array[l].val < array[r].val) { + tmp[pos++] = array[l++]; + } + else { + tmp[pos++] = array[r++]; + } + } + while (l <= mid) + tmp[pos++] = array[l++]; + while (r <= right) + tmp[pos++] = array[r++]; + for (i = 0; i < pos; ++i) + array[i+left] = tmp[i]; + } +} + +STACKELT *set_op_stack(stack, pos, op) + STACK *stack; + int pos; + OPER op; +{ + int size=stack->size; + STACKELT *pelt=stack->stack+pos; + + if (pos >= size) { + fprintf(stderr, "set_op: stack overflow: size=%d last=%d\n", size, pos); + return NULL; + } + pelt->op[pelt->nop++]=op; + pelt->op[pelt->nop]=End; + //pelt->val=val; + //stack->last++; + return pelt; +} + +STACKELT *set_ops_stack(stack, ops) + STACK *stack; + char *ops; +{ + //int size=stack->size; + int last=stack->last; + int i, j; /* 1st operator in on second number */ + STACKELT *pelt=stack->stack; + + printf("setting ops [%s]\n", (char *)ops); + for (i=1, j=0; i +#include +#include +#include "lceb.h" + +void gen_tree(seq, n, nb1, nb0) + int *seq; + int n; /* number of nodes */ + int nb1; /* number of "1" */ + int nb0; /* number of "0" */ +{ + int i; + + if((nb1 + nb0) == 2*n) { /* end */ + seq[2*n] = 0; + printf("tree="); + for (i=0; i<=2*n; ++i) + printf("%d", seq[i]); + putchar('\n'); + return; + } + + if(nb1 >= nb0 && nb1 < n) { + seq[nb1+nb0] = 1; + gen_tree(seq, n, nb1+1, nb0); + } + + if(nb0 < nb1 && nb1 <=n) { + seq[nb1+nb0] = 0; + gen_tree(seq, n, nb1, nb0+1); + } +} + +#ifdef STANDALONE +main(ac, av) + int ac; + char **av; +{ + int n; + int array[1024]; + n=atoi(av[1]); + gen_tree(array, n, 0, 0); + exit(0); +} +#endif