Added options (display, tree type...)
This commit is contained in:
28
best.c
28
best.c
@@ -13,7 +13,10 @@ static int bestops=MAXINT;
|
||||
|
||||
static BEST bests[1024*10]; /* TODO: should be dynamic */
|
||||
static int nbests=0;
|
||||
extern int displaytimer;
|
||||
int sigint_received=0;
|
||||
int displayintermediate=0;
|
||||
int displaytype=0;
|
||||
|
||||
#define DIFF(a, b) ((a)>(b)?(a)-(b):(b)-(a))
|
||||
|
||||
@@ -73,14 +76,16 @@ int check_best(res, nops, node, values, ops)
|
||||
bests[nbests].oper=ops;
|
||||
bests[nbests].root=dup_node(node);
|
||||
bests[nbests].values=values;
|
||||
# ifdef DEBUG_BEST
|
||||
// printf("NEW BEST! res=%d diff=%d nops=%d\n", res, diff, nops);
|
||||
printf("%.5f: diff=%d nops=%d %d=", get_timer(bests[nbests].timer),
|
||||
diff, nops, res);
|
||||
print_node(node, TREE_TOP, 0, 4);
|
||||
putchar('\n');
|
||||
if (displayintermediate) {
|
||||
if (displaytimer) {
|
||||
printf("%.5f secs: ", get_timer(bests[nbests].timer));
|
||||
}
|
||||
printf("diff=%d nops=%d %d=", diff, nops, res);
|
||||
print_node(node, TREE_TOP, 0, displaytype);
|
||||
putchar('\n');
|
||||
}
|
||||
//printf("check_best: res=%d diff=%d nops=%d\n", res, diff, nops);
|
||||
# endif
|
||||
nbests++;
|
||||
return diff;
|
||||
}
|
||||
@@ -115,12 +120,15 @@ void print_best(node, values, pops, depth)
|
||||
|
||||
void print_bests()
|
||||
{
|
||||
int i;
|
||||
printf("BEST SOLUTION: diff=%d ops=%d\n", bestdiff, bestops);
|
||||
int i=0;
|
||||
printf("BEST SOLUTION: res=%d diff=%d ops=%d ", bests[i].res, bestdiff, bestops);
|
||||
if (displaytimer)
|
||||
printf("after %.5f secs.", get_timer(bests[i].timer));
|
||||
putchar('\n');
|
||||
for (i=0; i<nbests; ++i) {
|
||||
//print_best(bests[i].root, bests[i].values, bests[i].oper, 0);
|
||||
printf("%.5f secs: %5d = ", get_timer(bests[i].timer), bests[i].res);
|
||||
print_node(bests[i].root, TREE_TOP, 0, 4);
|
||||
//printf("%5d =", bests[i].res);
|
||||
print_node(bests[i].root, TREE_TOP, 0, displaytype);
|
||||
putchar('\n');
|
||||
//printf("%3d: %d = ", i, bests[i].res);
|
||||
//print_node(bests[i].root, TREE_TOP, 0, 1);
|
||||
|
4
eval.c
4
eval.c
@@ -15,14 +15,12 @@ int eval_node(node, depth, pvals, pops, ncalcs)
|
||||
{
|
||||
static int *vals, *val_zero;
|
||||
static char *ops, *ops_zero;
|
||||
static NODE *node_zero;
|
||||
static int totcalc;
|
||||
int val1, val2, op, res=-1, i, lcalcs, rcalcs;
|
||||
int val1, val2, op, res=-1, lcalcs, rcalcs;
|
||||
|
||||
if (depth == 0) {
|
||||
val_zero=vals=pvals;
|
||||
ops_zero=ops=pops;
|
||||
node_zero=node;
|
||||
totcalc=0;
|
||||
}
|
||||
# ifdef DEBUG_EVAL
|
||||
|
149
lceb.c
149
lceb.c
@@ -1,7 +1,7 @@
|
||||
/* compte-est-bon.c - should one day solve this game...
|
||||
/* lceb - Countdown game solver.
|
||||
*
|
||||
* $ make compte-est-bon
|
||||
* $ ./compte-est-bon target n1 n2 [...n6]
|
||||
* $ make lceb
|
||||
* $ ./lceb target n1 n2 [...n6]
|
||||
*
|
||||
* At least 2 "n" are mandatory, and no more than 6 are allowed.
|
||||
*
|
||||
@@ -9,56 +9,145 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include "lceb.h"
|
||||
|
||||
#define TREE_CATALAN 0
|
||||
#define TREE_WEDDERBURN 1
|
||||
|
||||
static char *cmd;
|
||||
static int treetype=TREE_CATALAN;
|
||||
extern int displaytimer, displayintermediate, displaytype;
|
||||
int displaysummary=1;
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr, "usage: %s [options] target n1 n2 [...n%d]\n", cmd, MAXINPUT);
|
||||
}
|
||||
|
||||
void help()
|
||||
{
|
||||
usage();
|
||||
fprintf(stderr, "Countdown game solver.\n");
|
||||
fprintf(stderr, " -c: Show solutions timer\n");
|
||||
fprintf(stderr, " -d TYPE: Solutions display type. TYPE can be:\n");
|
||||
fprintf(stderr, " r: RPN (default)\n");
|
||||
fprintf(stderr, " p: Polish\n");
|
||||
fprintf(stderr, " l: Lisp\n");
|
||||
fprintf(stderr, " i: Infix (full parentheses)\n");
|
||||
fprintf(stderr, " d: Suitable for dc(1) input\n");
|
||||
fprintf(stderr, " t: Tree\n");
|
||||
fprintf(stderr, " -i: Show intermediate solutions\n");
|
||||
fprintf(stderr, " -s: Do not show summary (time, nodes evaluated)\n");
|
||||
fprintf(stderr, " -t: Use less trees (Wedderburn–Etherington instead of Catalan)\n");
|
||||
fprintf(stderr, " -h: this help:\n");
|
||||
}
|
||||
|
||||
int main(ac, av)
|
||||
int ac;
|
||||
char **av;
|
||||
{
|
||||
unsigned target;
|
||||
STACK inputstack = {
|
||||
"initial",
|
||||
MAXINPUT, /* size */
|
||||
0, /* last */
|
||||
NULL, /* next */
|
||||
{0}
|
||||
.name="initial",
|
||||
.size=MAXINPUT,
|
||||
.last=0,
|
||||
.next=NULL,
|
||||
.stack={0}
|
||||
};
|
||||
STACK *stack;
|
||||
int i, j, k, stacksize, val;
|
||||
int ncombs, nstacks, ntrees, nops;
|
||||
TREE *tree;
|
||||
char intarray[1024];
|
||||
int eval;
|
||||
char *comb;
|
||||
struct timespec end;
|
||||
char *options="thcisd:";
|
||||
int option;
|
||||
# ifdef DEBUG_MAIN
|
||||
int eval;
|
||||
# endif
|
||||
|
||||
setlocale(LC_ALL, ""); /* to use "%'d" in printf */
|
||||
if (ac < 4 || ac > 2+MAXINPUT) {
|
||||
fprintf(stderr, "usage: %s target n1 n2 [...n%d]\n", *av, MAXINPUT);
|
||||
cmd=*av;
|
||||
|
||||
while ((option = getopt(ac, av, options)) != -1) {
|
||||
//printf("opt: %c\n", option);
|
||||
switch (option) {
|
||||
case 'd':
|
||||
switch(*optarg) {
|
||||
case 'r':
|
||||
displaytype=0;
|
||||
break;
|
||||
case 'p':
|
||||
displaytype=1;
|
||||
break;
|
||||
case 'l':
|
||||
displaytype=3;
|
||||
break;
|
||||
case 'i':
|
||||
displaytype=4;
|
||||
break;
|
||||
case 't':
|
||||
displaytype=2;
|
||||
break;
|
||||
case 'd':
|
||||
displaytype=5;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown display type: %c\n", *optarg);
|
||||
fprintf(stderr, "Try '%s -h' for help\n", cmd);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
displayintermediate=1;
|
||||
break;
|
||||
case 'c':
|
||||
displaytimer=1;
|
||||
break;
|
||||
case 's':
|
||||
displaysummary=0;
|
||||
break;
|
||||
case 't':
|
||||
treetype=TREE_WEDDERBURN;
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr, "unknown option: %c\n", optopt);
|
||||
fprintf(stderr, "%s: -%c: invalid option\n", cmd, optopt);
|
||||
exit(1);
|
||||
case 'h':
|
||||
help();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ac-optind < 3 || ac-optind > MAXINPUT+1) {
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
setlocale(LC_ALL, ""); /* to use "%'d" in printf */
|
||||
start_timer();
|
||||
target=atoi(av[1]);
|
||||
stacksize=2*(ac-2)-1;
|
||||
nops=ac-2-1;
|
||||
target=atoi(av[optind]);
|
||||
stacksize=ac-optind-1;
|
||||
nops=stacksize-1;
|
||||
|
||||
gen_combinations(nops);
|
||||
//ncombs=ncombinations(len_ops, nops);
|
||||
ncombs=n_combs();
|
||||
//print_combs();
|
||||
printf("target=%d\nstacksize=%d\n", target, stacksize);
|
||||
printf("target=%d\nstacksize=%d ", target, stacksize);
|
||||
set_target(target);
|
||||
//printf("len_ops=%d\nnops=%d\nops_comb=%d\n", len_ops, nops, ncombs);
|
||||
//stack=new_stack(stacksize, "Main Stack", 1);
|
||||
//strcpy(inputstack.name, "initial");
|
||||
for (i=2; i<ac; ++i) {
|
||||
for (i=optind+1; i<ac; ++i) {
|
||||
val=atoi(av[i]);
|
||||
push_stack(&inputstack, val);
|
||||
}
|
||||
print_stack(&inputstack, 0);
|
||||
|
||||
//print_stack(stack, 1);
|
||||
gen_stacks(&inputstack); // printf("sorting stack...\n");
|
||||
@@ -73,12 +162,17 @@ int main(ac, av)
|
||||
} while (permute_stack(stack->stack, stack->last));
|
||||
*/
|
||||
|
||||
//gen_tree(intarray, nops, 0, 0);
|
||||
gen_reduced_trees(nops+1);
|
||||
if (treetype==TREE_CATALAN) {
|
||||
gen_tree(intarray, nops, 0, 0);
|
||||
} else {
|
||||
gen_reduced_trees(nops+1);
|
||||
}
|
||||
nstacks=n_stacks();
|
||||
ntrees=n_trees();
|
||||
printf("stacks=%d\noperators combinations=%d\ntrees=%d\n",
|
||||
nstacks, ncombs, ntrees);
|
||||
printf("stacks :%'15d\n", nstacks);
|
||||
printf("ops combinations:%'15d\n", ncombs);
|
||||
printf("trees :%'15d\n", ntrees);
|
||||
printf("max evaluations :%'15d\n", nstacks*ncombs*ntrees*stacksize);
|
||||
//for (k=0; k<nstacks; ++k) {
|
||||
// stack=nth_stack(k);
|
||||
// printf("%%%%%%%%%%%%%%%%%%\n");
|
||||
@@ -95,8 +189,8 @@ int main(ac, av)
|
||||
//printf("%%%%%%%%%%%%%%%%%%\n");
|
||||
//print_stack(stack, 0);
|
||||
//printf("%%%%%%%%%%%%%%%%%%\n");
|
||||
# ifdef DEBUG_MAIN
|
||||
eval=eval_node(tree->head, 0, stack->stack, comb, &ncalcs);
|
||||
#ifdef DEBUG1
|
||||
if (eval > 0) {
|
||||
printf("============================== %d, %d, %d\n", i, j, k);
|
||||
print_tree(tree, 0);
|
||||
@@ -105,7 +199,9 @@ int main(ac, av)
|
||||
printf("eval=%d - calcs=%d\n", eval, ncalcs);
|
||||
|
||||
}
|
||||
#endif
|
||||
# else
|
||||
eval_node(tree->head, 0, stack->stack, comb, &ncalcs);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
//opscomb=combination(ops, nops, i);
|
||||
@@ -121,7 +217,8 @@ int main(ac, av)
|
||||
printf("\n");
|
||||
print_bests();
|
||||
set_timer(&end);
|
||||
printf("Total time elapsed: %.5f secs, nodes/leaves evaluated:%'d/%'d\n",
|
||||
get_timer(end), get_totnodes(), get_totleaves());
|
||||
if (displaysummary)
|
||||
printf("Total time elapsed: %.5f secs, nodes/leaves evaluated:%'d/%'d\n",
|
||||
get_timer(end), get_totnodes(), get_totleaves());
|
||||
exit(0);
|
||||
}
|
||||
|
4
lceb.h
4
lceb.h
@@ -84,7 +84,7 @@ extern int n_trees();
|
||||
/* stack.c */
|
||||
extern void print_stack(STACK *stack, int details);
|
||||
extern void print_stacks();
|
||||
extern int keep_stack(STACK *stack);
|
||||
//extern int keep_stack(STACK *stack);
|
||||
//extern STACK *new_stack(int size, char *name, int keep);
|
||||
extern STACK *new_stack(int size, char *name, int keep);
|
||||
extern int *push_stack(STACK *stack, int val);
|
||||
@@ -92,7 +92,7 @@ extern int *pop_stack(STACK *stack);
|
||||
extern STACK *dup_stack(STACK *stack, char *name);
|
||||
extern void swap_stack(int *elts, int i, int j);
|
||||
extern int permute_stack(int *array, int n);
|
||||
extern int gen_stacks(STACK *stack);
|
||||
extern void gen_stacks(STACK *stack);
|
||||
extern void mergesort_stack(int *array, int left, int right);
|
||||
extern STACK *nth_stack(int n);
|
||||
extern int n_stacks();
|
||||
|
9
oper.c
9
oper.c
@@ -44,6 +44,9 @@ static char *combine(ops, len, n)
|
||||
|
||||
if (!res) { // 1st call
|
||||
len_ops=strlen(ops);
|
||||
# ifdef DEBUG_MEM
|
||||
printf("mem: allocating operators working area (%d bytes)\n", len+1);
|
||||
# endif
|
||||
res=malloc(len * sizeof(char) + 1);
|
||||
}
|
||||
for(i=0; i<len; ++i){
|
||||
@@ -59,7 +62,9 @@ void gen_combinations(nops)
|
||||
char *ops="+-*/";
|
||||
int i, n_combs;
|
||||
int len_ops=strlen(ops);
|
||||
|
||||
# ifdef DEBUG_OPER
|
||||
printf("gen_combinations(%d)\n", nops);
|
||||
# endif
|
||||
n_combs=n_combine(len_ops, nops);
|
||||
//printf("gen: n=%d\n", n_combs);
|
||||
for (i=0; i<n_combs; ++i) {
|
||||
@@ -84,7 +89,7 @@ int main(ac, av)
|
||||
{
|
||||
char *ops="+-*/", *p;
|
||||
int len_ops=strlen(ops);
|
||||
int i, j, nops, ncombs;
|
||||
int i, nops, ncombs;
|
||||
|
||||
nops=atoi(*(av+1));
|
||||
ncombs=n_combine(len_ops, nops);
|
||||
|
64
stack.c
64
stack.c
@@ -1,13 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include "lceb.h"
|
||||
|
||||
static STACK *stacks=NULL;
|
||||
static STACK *allstacks=NULL;
|
||||
static int nstacks=0;
|
||||
static int totalstacks=0;
|
||||
static int laststack=0;
|
||||
int totalstacks=0;
|
||||
int laststack=0;
|
||||
|
||||
void print_stack(stack, details)
|
||||
STACK *stack;
|
||||
@@ -44,33 +44,31 @@ void print_stacks()
|
||||
}
|
||||
}
|
||||
|
||||
int keep_stack(stack)
|
||||
STACK *stack;
|
||||
{
|
||||
stack->next=stacks;
|
||||
stacks=stack;
|
||||
nstacks++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
STACK *new_stack(size, name, keep)
|
||||
int size; /* 0 if empty */
|
||||
int size; /* unused */
|
||||
char *name;
|
||||
int keep;
|
||||
{
|
||||
STACK *stack;
|
||||
int *pelt;
|
||||
int i;
|
||||
|
||||
# ifdef DEBUG_STACK
|
||||
printf("new_stack(size=%d, name=[%s] last=%d total=%d)\n",
|
||||
size, name, laststack, totalstacks);
|
||||
# endif
|
||||
if (!allstacks) {
|
||||
totalstacks=ALLOCSIZE;
|
||||
printf("new_stack %d: allocating %d stacks\n", laststack, totalstacks);
|
||||
# ifdef DEBUG_MEM
|
||||
printf("new_stack: allocating %d stacks\n", totalstacks);
|
||||
# endif
|
||||
allstacks=malloc(totalstacks*sizeof (STACK));
|
||||
}
|
||||
if (laststack==totalstacks) {
|
||||
totalstacks+=ALLOCSIZE;
|
||||
printf("new_stack %d: resizing stacks array to %d\n", laststack, totalstacks);
|
||||
allstacks=realloc(stacks, totalstacks*sizeof (STACK));
|
||||
# ifdef DEBUG_MEM
|
||||
printf("new_stack: resizing stacks array to %d\n", totalstacks);
|
||||
# endif
|
||||
allstacks=realloc(allstacks, totalstacks*sizeof (STACK));
|
||||
}
|
||||
|
||||
stack=allstacks+laststack;
|
||||
@@ -86,8 +84,8 @@ STACK *new_stack(size, name, keep)
|
||||
//pelt=malloc(size*sizeof(int));
|
||||
stack->size=MAXINPUT;
|
||||
//stack->stack=pelt;
|
||||
if (keep)
|
||||
keep_stack(stack);
|
||||
//if (keep)
|
||||
// keep_stack(stack);
|
||||
for (i=0; i<MAXINPUT; ++i) {
|
||||
//(pelt+i)->nop=0;
|
||||
//(pelt+i)->curop=0;
|
||||
@@ -107,13 +105,15 @@ int *push_stack(stack, val)
|
||||
int size=stack->size;
|
||||
int *pelt=stack->stack+stack->last;
|
||||
|
||||
#ifdef DEBUG_STACK
|
||||
printf("push_stack(%d): last=%d size=%d\n", val, stack->last, stack->size);
|
||||
#endif
|
||||
# ifdef DEBUG_STACK
|
||||
printf("push_stack(%d:[%s]): last=%d size=%d\n",
|
||||
val, stack->name, stack->last, stack->size);
|
||||
# endif
|
||||
|
||||
if (pos >= size) {
|
||||
fprintf(stderr, "stack overflow: size=%d last=%d\n", size, pos);
|
||||
return NULL;
|
||||
fprintf(stderr, "stack overflow: size=%d last=%d. generating core.\n", size, pos);
|
||||
raise(SIGABRT);
|
||||
return NULL; /* useless, we died */
|
||||
}
|
||||
//pelt->nop=0;
|
||||
//pelt->curop=0;
|
||||
@@ -127,11 +127,12 @@ int *pop_stack(stack)
|
||||
STACK *stack;
|
||||
{
|
||||
int pos=stack->last+1;
|
||||
int size=stack->size;
|
||||
int *pelt=stack->stack+stack->last;
|
||||
|
||||
if (pos==0) {
|
||||
fprintf(stderr, "stack empty: size=%d last=%d\n", size, pos);
|
||||
# ifdef DEBUG_STACK
|
||||
printf("pop: empty stack [%s]: size=%d last=%d\n", stack->name, stack->size, pos);
|
||||
# endif
|
||||
return NULL;
|
||||
}
|
||||
stack->last--;
|
||||
@@ -143,7 +144,7 @@ STACK *dup_stack(stack, name)
|
||||
char *name;
|
||||
{
|
||||
STACK *new;
|
||||
int *src=stack->stack, *dst;
|
||||
int *dst;
|
||||
int size=stack->size, last=stack->last, i;
|
||||
|
||||
new=new_stack(size, name, 0);
|
||||
@@ -192,24 +193,25 @@ int permute_stack(array, n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gen_stacks(stack)
|
||||
void gen_stacks(stack)
|
||||
STACK *stack;
|
||||
{
|
||||
char name[80];
|
||||
int last=stack->last;
|
||||
int n=1;
|
||||
STACK *new;
|
||||
int exists=1;
|
||||
|
||||
printf("sorting stack...\n");
|
||||
printf("last=%d laststack=%d totalstacks=%d\n", last, laststack, totalstacks);
|
||||
//printf("before sort: ");
|
||||
//print_stack(stack, 0);
|
||||
mergesort_stack(stack->stack, 0, last-1);
|
||||
printf("last=%d total=%d\n", laststack, totalstacks);
|
||||
//printf("after sort: ");
|
||||
//print_stack(stack, 0);
|
||||
// push initial stack
|
||||
//printf("++++++++++++++++ Adding main stack... ");
|
||||
new=dup_stack(stack, "Main stack");
|
||||
dup_stack(stack, "Main stack");
|
||||
//keep_stack(new);
|
||||
//print_stacks();
|
||||
//print_stack(stack, 1);
|
||||
@@ -221,7 +223,7 @@ int gen_stacks(stack)
|
||||
//print_stack(stack, 0);
|
||||
if (exists) {
|
||||
//printf("++++++++++++++++ Adding stack... ");
|
||||
new=dup_stack(stack, name);
|
||||
dup_stack(stack, name);
|
||||
// print_stack(new, 0);
|
||||
//keep_stack(new);
|
||||
}
|
||||
|
Reference in New Issue
Block a user