/* * Program for helping with keen (a Kenken derivative) puzzles. * * Input consists of lines of the form * * * * where must be + or *, is the number of cells in the * box, is the grid size (and maximum number), and is * what the operation results in. For example, a three-cell box * marked "48*" in a 6x6 puzzle would be * * * 3 6 48 * * Since it doesn't know the shape, this lists all possible * arrangements, even though some of them may be impossible in some * cases. (It even lists always-impossible cases like "4 4 4" for "+ * 3 6 12".) */ #include #include extern const char *__progname; static char *b = 0; static int a = 0; static int l; static void linesave(char c) { if (l >= a) b = realloc(b,a=l+8); b[l++] = c; } static void rdline(void) { int c; l = 0; while (1) { c = getchar(); if (c == EOF) exit(0); if (c == '\n') break; linesave(c); } linesave('\0'); } static int fn_add(int a, int b) { return(a+b); } static int fn_mul(int a, int b) { return(a*b); } static void search(int size, int min, int count, int *v, int nsofar, int vsofar, int (*fn)(int, int), int target) { int i; if (nsofar >= count) { if (vsofar == target) { for (i=0;i target) return; for (i=min;i<=size;i++) { v[nsofar] = i; search(size,i,count,v,nsofar+1,(*fn)(vsofar,i),fn,target); } } int main(void); int main(void) { char opc; int count; int size; int value; int n1; int n2; int (*fn)(int, int); int *v; int va; int ival; v = 0; va = 0; while (1) { rdline(); n1 = -1; n2 = -1; sscanf(b," %c %d %d %d %n%*c%n",&opc,&count,&size,&value,&n1,&n2); if (n1 < 0) { printf("Input line format: op count size value\n"); continue; } switch (opc) { case '+': fn = &fn_add; ival = 0; break; case '*': fn = &fn_mul; ival = 1; break; default: printf("op must be + or *\n"); exit(1); break; } if (count > va) { free(v); va = count; v = malloc(va*sizeof(int)); } search(size,1,count,v,0,ival,fn,value); } }