/* lceb - Countdown game solver. * * $ make lceb * $ ./lceb target n1 n2 [...n6] * * At least 2 "n" are mandatory, and no more than 6 are allowed. * */ #include #include #include #include #include #include #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 (binary operators)\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 = { .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]; char *comb; struct timespec end; char *options="thcisd:"; int option; # ifdef DEBUG_MAIN int eval; # endif 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[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 ", 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=optind+1; 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)); */ if (treetype==TREE_CATALAN) { gen_tree(intarray, nops, 0, 0); } else { gen_reduced_trees(nops); } nstacks=n_stacks(); ntrees=n_trees(); 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; khead, 0, stack->stack, comb, &ncalcs); if (eval > 0) { printf("============================== %d, %d, %d\n", i, j, k); print_tree(tree, 0); print_comb(j); print_stack(stack, 0); printf("eval=%d - calcs=%d\n", eval, ncalcs); } # else eval_node(tree->head, 0, stack->stack, comb, &ncalcs); # endif } } //opscomb=combination(ops, nops, i); //printf("OPS=%s\n", opscomb); //eval=eval_node(tree->head, 0, stack->stack, nth_comb(0)); //printf("eval=%d\n", eval); //set_ops_stack(stack, opscomb); //print_stack(stack, 0); //res=eval_stack(stack); //printf("EVAL=%d\n", res); } printf("\n"); print_bests(); set_timer(&end); if (displaysummary) printf("Total time elapsed: %.5f secs, nodes/leaves evaluated:%'d/%'d\n", get_timer(end), get_totnodes(), get_totleaves()); exit(0); }