commit 0b6c839b4df50bd76d7cc341c0e650edbcfe5e77 Author: Bruno Raoult Date: Wed Jan 20 16:22:59 2021 +0100 initial version 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