Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h> /* for printf */
- /* constants declaration */
- #define TOTAL 24.f
- #define PRECISION 0.1f
- #define MAX_POINT 13
- #define MIN_POINT 1
- #define NUM_CARDS 4
- /* stack operation */
- float _stack[NUM_CARDS];
- int _top = 0;
- #define push(num) (_stack[_top++] = (num))
- #define pop() (_stack[--_top])
- #define top() (_stack[_top - 1])
- #define clear() (_top = 0)
- /* procedure declaration */
- typedef float op_type(float, float);
- float op_plus(float, float);
- float op_minus(float, float);
- float op_multiply(float, float);
- float op_divide(float, float);
- const char *precedences[] = {
- "nnonono",
- "nnonnoo",
- "nnnoono",
- "nnnonoo",
- "nnnnooo",
- 0
- };
- op_type *operators[] = {
- &op_plus,
- &op_minus,
- &op_multiply,
- &op_divide,
- 0
- };
- /* operators implement */
- float op_plus(float lhs, float rhs)
- {
- return lhs + rhs;
- }
- float op_minus(float lhs, float rhs)
- {
- return lhs - rhs;
- }
- float op_multiply(float lhs, float rhs)
- {
- return lhs * rhs;
- }
- float op_divide(float lhs, float rhs)
- {
- return lhs / rhs;
- }
- /* internal functions declaration */
- int test(const char *prec, op_type ***opr_buf, int *num_buf);
- int cycle_precedence(const char ***pprec);
- int cycle_operator(op_type ***popr);
- int cycle_number(int *n);
- void print(const char *prec, op_type ***opr, int *num, int n);
- void procedure(void);
- /* body */
- int test(const char *prec, op_type ***opr_buf, int *num_buf)
- {
- const char *pprec = prec;
- op_type ***popr = opr_buf;
- int *pnum = num_buf;
- clear();
- while (*pprec) {
- if (*pprec == 'n') {
- push((float)(*pnum++));
- } else if (*pprec == 'o') {
- float o1, o2;
- o1 = pop();
- o2 = pop();
- push((***popr++)(o1, o2));
- } else {
- /* error */
- }
- ++pprec;
- }
- if (top() >= TOTAL - PRECISION &&
- top() <= TOTAL + PRECISION)
- return 1;
- return 0;
- }
- int cycle_precedence(const char ***pprec)
- {
- if (*(*pprec + 1)) {
- ++(*pprec);
- return 0;
- }
- *pprec = &precedences[0];
- return 1;
- }
- int _cycle_operator(op_type ***popr, int index)
- {
- if (index < 0)
- return 1;
- if (*(popr[index]+1) != 0) {
- ++popr[index];
- return 0;
- }
- popr[index] = &operators[0];
- return _cycle_operator(popr, index - 1);
- }
- int cycle_operator(op_type ***popr)
- {
- return _cycle_operator(popr, NUM_CARDS - 2);
- }
- int _cycle_number(int *n, int index)
- {
- if (index < 0)
- return 1;
- if (n[index] < MAX_POINT) {
- ++(n[index]);
- return 0;
- }
- n[index] = MIN_POINT;
- return _cycle_number(n, index - 1);
- }
- int cycle_number(int *n)
- {
- return _cycle_number(n, NUM_CARDS - 1);
- }
- char _opr_chr(op_type *opr)
- {
- if (opr == &op_plus)
- return '+';
- else if (opr == &op_minus)
- return '-';
- else if (opr == &op_multiply)
- return '*';
- else if (opr == &op_divide)
- return '/';
- else
- return '?';
- }
- void print(const char *prec, op_type ***opr, int *num, int n)
- {
- printf("%5d: (%d,%d,%d,%d) %s (%c,%c,%c)\n",
- n, num[0], num[1], num[2], num[3], prec,
- _opr_chr(*opr[0]), _opr_chr(*opr[1]), _opr_chr(*opr[2]));
- }
- void procedure(void)
- {
- int num_buf[NUM_CARDS];
- op_type **opr_buf[NUM_CARDS - 1];
- const char **prec = &precedences[0];
- int counting = 0;
- int i = 0;
- while (i != NUM_CARDS) {
- num_buf[i++] = MIN_POINT;
- }
- i = 0;
- while (i != NUM_CARDS - 1) {
- opr_buf[i++] = &operators[0];
- }
- do {
- do {
- do {
- if (test(*prec, opr_buf, num_buf))
- print(*prec, opr_buf, num_buf, ++counting);
- } while (!cycle_precedence(&prec));
- } while (!cycle_operator(opr_buf));
- } while (!cycle_number(num_buf));
- }
- int main(void)
- {
- procedure();
- return 0;
- }
Add Comment
Please, Sign In to add comment