按 ‘ 二十四点 ’ 标签归档

二十四点

这是一个算二十四点的程序。从命令行输入四个数字,结果以后缀表达式输出。如:

$ 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];
}