#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define N 6
#define OPERATOR_ADD 0
#define OPERATOR_SUBTRACT 1
#define OPERATOR_MULTIPLY 2
#define OPERATOR_DIVIDE 3
int operands[N], result;
int stack[N + 4];
bool bUsed[N];
#define MAX_RESULT 256
void EvalStack(int nStackDepth)
{
int i, nIntResult;
int workingspace[N + 4], j;
static char szResult[MAX_RESULT];
static char szStackStrings[N + 4][MAX_RESULT];
j = 0;
for (i = 0; i < nStackDepth; i++)
{
if (stack[i] >= N)
{
if (j < 2)
{
printf("Stack is not well formed!\n");
return;
}
switch (stack[i] - N)
{
case OPERATOR_ADD:
nIntResult = workingspace[j - 1] + workingspace[j - 2];
sprintf(szResult, "(%s + %s)", szStackStrings[j - 1], szStackStrings[j - 2]);
break;
case OPERATOR_SUBTRACT:
nIntResult = workingspace[j - 1] - workingspace[j - 2];
sprintf(szResult, "(%s - %s)", szStackStrings[j - 1], szStackStrings[j - 2]);
break;
case OPERATOR_MULTIPLY:
if ((workingspace[j - 1] == 1) || (workingspace[j - 2] == 1))
return;
nIntResult = workingspace[j - 1] * workingspace[j - 2];
sprintf(szResult, "(%s * %s)", szStackStrings[j - 1], szStackStrings[j - 2]);
break;
case OPERATOR_DIVIDE:
if (workingspace[j - 2] == 1)
return;
if ((workingspace[j - 1] % workingspace[j - 2]) > 0)
return;
nIntResult = workingspace[j - 1] / workingspace[j - 2];
sprintf(szResult, "(%s / %s)", szStackStrings[j - 1], szStackStrings[j - 2]);
break;
}
if (nIntResult <= 0)
{
return;
}
j--;
workingspace[j - 1] = nIntResult;
strcpy(szStackStrings[j - 1], szResult);
}
else
{
workingspace[j] = operands[stack[i]];
sprintf(szStackStrings[j], "%d", operands[stack[i]]);
j++;
}
}
if (j < 1)
{
printf("Stack is corrupt!\n");
return;
}
if (workingspace[j - 1] == result)
{
printf("%s = %d\n", szStackStrings[j - 1], workingspace[j - 1]);
}
}
void BuildStacks(int nOperandsUsed = 0, int nStackDepth = 0)
{
int i;
if ((nOperandsUsed - (nStackDepth - nOperandsUsed)) == 1)
EvalStack(nStackDepth);
if (nStackDepth == (N + 4))
return;
for (i = 0; i < (N + 4); i++)
{
if ((i >= N) || !bUsed[i])
{
stack[nStackDepth] = i;
if (i >= N)
{
if ((nOperandsUsed - (nStackDepth - nOperandsUsed)) > 1)
BuildStacks(nOperandsUsed, nStackDepth + 1);
}
else
{
bUsed[i] = true;
BuildStacks(nOperandsUsed + 1, nStackDepth + 1);
bUsed[i] = false;
}
}
}
}
int main(int argc, char *argv[])
{
int i;
printf("Countdown solver v1.0\n");
printf(" Copyright (C) David McCabe, 2000.\n\n");
if (argc < (N + 2))
{
printf("countdown: Usage: countdown result (numbers)\n");
return 1;
}
result = atoi(argv[1]);
if (result <= 0)
printf("countdown: Result should be a positive natural number greater than 0.\n");
for (i = 0; i < N; i++)
{
operands[i] = atoi(argv[i + 2]);
if (operands[i] <= 0)
{
printf("countdown: Operands should be positive natural numbers greater than 0.\n");
return 2;
}
}
printf("Combining numbers: ");
for (i = 0; i < N; i++)
printf("%d ", operands[i]);
printf("to make %d\n", result);
clock_t start, finish;
start = clock();
BuildStacks();
finish = clock();
printf("Time taken: %.3f seconds\n", (double)(finish - start) / CLOCKS_PER_SEC);
return 0;
}