二十四点
- 2003年07月12日
这是一个算二十四点的程序。从命令行输入四个数字,结果以后缀表达式输出。如:
$ calc24 8 8 3 3 8383/-/
即8/(3-8/3)。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> void calc24(int, int, int, int); double calc(char *); void main(int argc, char *argv[]) { int n[4]; int i, j, k, m; if (argc != 5) { printf("Usage: %s a b c d\n", argv[0]); return; } for (i = 0; i < 4; i++) if ((n[i] = atoi(argv[i+1])) < 1 || n[i] > 9) { printf("%s is not a valid input\n", argv[i+1]); return; } for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { if (j == i) continue; for (k = 0; k < 4; k++) { if (k == i || k == j) continue; for (m = 0; m < 4; m++) { if (m == i || m == j || m == k) continue; calc24(n[i], n[j], n[k], n[m]); } } } } void calc24(int a, int b, int c, int d) { char expr[10]; char *oper = "+-*/"; int i, j, k, m; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { for (k = 0; k < 4; k++) { sprintf(expr, "%d%d%d%d%c%c%c", a, b, c, d, oper[i], oper[j], oper[k]); if (fabs(calc(expr) - 24) < 1.0E-3) puts(expr); sprintf(expr, "%d%d%d%c%d%c%c", a, b, c, oper[i], d, oper[j], oper[k]); if (fabs(calc(expr) - 24) < 1.0E-3) puts(expr); sprintf(expr, "%d%d%d%c%c%d%c", a, b, c, oper[i], oper[j], d, oper[k]); if (fabs(calc(expr) - 24) < 1.0E-3) puts(expr); sprintf(expr, "%d%d%c%d%d%c%c", a, b, oper[i], c, d, oper[j], oper[k]); if (fabs(calc(expr) - 24) < 1.0E-3) puts(expr); sprintf(expr, "%d%d%c%d%c%d%c", a, b, oper[i], c, oper[j], d, oper[k]); if (fabs(calc(expr) - 24) < 1.0E-3) puts(expr); } } } double calc(char *expr) { double a, b, stack[4]; int top, i, n; n = strlen(expr); top = 0; for (i = 0; i < n; i++) { if (isdigit(expr[i])) { stack[top++] = expr[i] - '0'; continue; } if (top < 2) return 9999; b = stack[--top]; a = stack[--top]; switch(expr[i]) { case '+': stack[top] = a + b; break; case '-': stack[top] = a - b; break; case '*': stack[top] = a * b; break; case '/': if (b == 0.0) return 9999; stack[top] = a / b; break; } top++; } if (top != 1) return -9999; return stack[0]; }