Guest User

Untitled

a guest
Jun 25th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.61 KB | None | 0 0
  1. #include <stdio.h>  /* for printf */
  2.  
  3. /* constants declaration */
  4. #define TOTAL 24.f
  5. #define PRECISION 0.1f
  6. #define MAX_POINT 13
  7. #define MIN_POINT 1
  8. #define NUM_CARDS 4
  9.  
  10.  
  11.  
  12. /* stack operation */
  13. float _stack[NUM_CARDS];
  14. int _top = 0;
  15.  
  16. #define push(num) (_stack[_top++] = (num))
  17. #define pop() (_stack[--_top])
  18. #define top() (_stack[_top - 1])
  19. #define clear() (_top = 0)
  20.  
  21.  
  22. /* procedure declaration */
  23. typedef float op_type(float, float);
  24.  
  25. float op_plus(float, float);
  26. float op_minus(float, float);
  27. float op_multiply(float, float);
  28. float op_divide(float, float);
  29.  
  30. const char *precedences[] = {
  31.     "nnonono",
  32.     "nnonnoo",
  33.     "nnnoono",
  34.     "nnnonoo",
  35.     "nnnnooo",
  36.     0
  37. };
  38.  
  39. op_type *operators[] = {
  40.     &op_plus,
  41.     &op_minus,
  42.     &op_multiply,
  43.     &op_divide,
  44.     0
  45. };
  46.  
  47. /* operators implement */
  48.  
  49. float op_plus(float lhs, float rhs)
  50. {
  51.     return lhs + rhs;
  52. }
  53. float op_minus(float lhs, float rhs)
  54. {
  55.     return lhs - rhs;
  56. }
  57. float op_multiply(float lhs, float rhs)
  58. {
  59.     return lhs * rhs;
  60. }
  61. float op_divide(float lhs, float rhs)
  62. {
  63.     return lhs / rhs;
  64. }
  65.  
  66.  
  67. /* internal functions declaration */
  68. int test(const char *prec, op_type ***opr_buf, int *num_buf);
  69. int cycle_precedence(const char ***pprec);
  70. int cycle_operator(op_type ***popr);
  71. int cycle_number(int *n);
  72. void print(const char *prec, op_type ***opr, int *num, int n);
  73. void procedure(void);
  74.  
  75.  
  76. /* body */
  77. int test(const char *prec, op_type ***opr_buf, int *num_buf)
  78. {
  79.     const char *pprec = prec;
  80.     op_type ***popr = opr_buf;
  81.     int *pnum = num_buf;
  82.  
  83.     clear();
  84.  
  85.     while (*pprec) {
  86.         if (*pprec == 'n') {
  87.             push((float)(*pnum++));
  88.         } else if (*pprec == 'o') {
  89.             float o1, o2;
  90.             o1 = pop();
  91.             o2 = pop();
  92.             push((***popr++)(o1, o2));
  93.         } else {
  94.             /* error */
  95.         }
  96.  
  97.         ++pprec;
  98.     }
  99.  
  100.     if (top() >= TOTAL - PRECISION &&
  101.         top() <= TOTAL + PRECISION)
  102.         return 1;
  103.  
  104.     return 0;
  105. }
  106.  
  107. int cycle_precedence(const char ***pprec)
  108. {
  109.     if (*(*pprec + 1)) {
  110.         ++(*pprec);
  111.         return 0;
  112.     }
  113.  
  114.     *pprec = &precedences[0];
  115.     return 1;
  116. }
  117.  
  118. int _cycle_operator(op_type ***popr, int index)
  119. {
  120.     if (index < 0)
  121.         return 1;
  122.  
  123.     if (*(popr[index]+1) != 0) {
  124.         ++popr[index];
  125.         return 0;
  126.     }
  127.  
  128.     popr[index] = &operators[0];
  129.  
  130.     return _cycle_operator(popr, index - 1);
  131. }
  132.  
  133. int cycle_operator(op_type ***popr)
  134. {
  135.     return _cycle_operator(popr, NUM_CARDS - 2);
  136. }
  137.  
  138. int _cycle_number(int *n, int index)
  139. {
  140.     if (index < 0)
  141.         return 1;
  142.  
  143.     if (n[index] < MAX_POINT) {
  144.         ++(n[index]);
  145.         return 0;
  146.     }
  147.  
  148.     n[index] = MIN_POINT;
  149.  
  150.     return _cycle_number(n, index - 1);
  151. }
  152.  
  153. int cycle_number(int *n)
  154. {
  155.     return _cycle_number(n, NUM_CARDS - 1);
  156. }
  157.  
  158. char _opr_chr(op_type *opr)
  159. {
  160.     if (opr == &op_plus)
  161.         return '+';
  162.     else if (opr == &op_minus)
  163.         return '-';
  164.     else if (opr == &op_multiply)
  165.         return '*';
  166.     else if (opr == &op_divide)
  167.         return '/';
  168.     else
  169.         return '?';
  170. }
  171.  
  172. void print(const char *prec, op_type ***opr, int *num, int n)
  173. {
  174.     printf("%5d: (%d,%d,%d,%d) %s (%c,%c,%c)\n",
  175.            n, num[0], num[1], num[2], num[3], prec,
  176.            _opr_chr(*opr[0]), _opr_chr(*opr[1]), _opr_chr(*opr[2]));
  177. }
  178.  
  179. void procedure(void)
  180. {
  181.     int num_buf[NUM_CARDS];
  182.     op_type **opr_buf[NUM_CARDS - 1];
  183.     const char **prec = &precedences[0];
  184.     int counting = 0;
  185.  
  186.     int i = 0;
  187.     while (i != NUM_CARDS) {
  188.         num_buf[i++] = MIN_POINT;
  189.     }
  190.     i = 0;
  191.     while (i != NUM_CARDS - 1) {
  192.         opr_buf[i++] = &operators[0];
  193.     }
  194.  
  195.     do {
  196.         do {
  197.             do {
  198.                 if (test(*prec, opr_buf, num_buf))
  199.                     print(*prec, opr_buf, num_buf, ++counting);
  200.             } while (!cycle_precedence(&prec));
  201.         } while (!cycle_operator(opr_buf));
  202.     } while (!cycle_number(num_buf));
  203. }
  204.  
  205.  
  206. int main(void)
  207. {
  208.     procedure();
  209.  
  210.     return 0;
  211. }
Add Comment
Please, Sign In to add comment