Files
Le-Compte-est-Bon/lceb.c

225 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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 <stdio.h>
#include <stdlib.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 (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 (WedderburnEtherington 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; 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");
//print_stacks();
//mergesort_stack(stack->stack, 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; k<nstacks; ++k) {
// stack=nth_stack(k);
// printf("%%%%%%%%%%%%%%%%%%\n");
// print_stack(stack, 0);
// printf("%%%%%%%%%%%%%%%%%%\n");
//}
for (i=0; i<ntrees; ++i) {
tree=nth_tree(i);
for (j=0; j<ncombs; ++j) {
comb=nth_comb(j);
for (k=0; k<nstacks; ++k) {
int ncalcs=0;
stack=nth_stack(k);
//printf("%%%%%%%%%%%%%%%%%%\n");
//print_stack(stack, 0);
//printf("%%%%%%%%%%%%%%%%%%\n");
# ifdef DEBUG_MAIN
eval=eval_node(tree->head, 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);
}