#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define STACK_SIZE 100       /*スタックのサイズ*/
#define ERROR 1000000.0      /*エラーが起きたときに返す数．演算結果と同じにならないように大きな数を返すようにしている．*/
#define STR_LEN 100          /*式を格納する文字列の大きさ*/
#define RANGE 10             /*探索する個数．0からRANGE-1までの式を探す．*/
/*逆ポーランド電卓の計算で用いるスタックに燗する実装*/
double d_stack[STACK_SIZE];                    /*スタック*/
int d_sp = 0;                                  /*スタックポインタ*/
/*スタックからプッシュする．*/
void d_push(double f)
{
  if (d_sp < STACK_SIZE) d_stack[d_sp++] = f;
  else printf("error: stack full, can't push %g\n", f);
}
/*スタックからポップする．*/
double d_pop()
{
  if (d_sp > 0) return d_stack[--d_sp];
  else{
    printf("error: stack empty\n");
    return 0.0;
  }
}
/*スタックを初期化する．*/
void d_init()
{
  d_sp = 0;
}
/*逆ポーランド記法で書かれた式aを計算した結果を返す関数．*/
double calc(char *a,int length)
{
  int i;
  double op2;
  d_init();
  for(i = 0;i < length;i++){
    if(isdigit(a[i])){
      d_push((double)(a[i] - '0'));
    }
    else if(a[i] == '+'){
      d_push(d_pop()+d_pop());
    }
    else if(a[i] == '-'){
      op2 =d_pop();
      d_push(d_pop()-op2);
    }
    else if(a[i] == '*'){
      d_push(d_pop()*d_pop());
    }
    else if(a[i] == '/'){
      op2 = d_pop();
      if(op2 == 0.0) return ERROR;
      else d_push(d_pop()/op2);
    }
  }
  return d_pop();
}
/*中間記法に変換するのにもちいるスタックの実装*/
char s_stack[STACK_SIZE][STR_LEN];
int s_sp = 0;
/*逆ポーランド記法で書かれた式aを中間記法で書いた結果をbに格納する*/
void toInfix(char *a,int length,char *b)
{
  int i;
  char tmp[STR_LEN];
  s_sp = 0;
  for(i = 0;i< length;i++){
    if(isdigit(a[i])){
      sprintf(s_stack[s_sp++],"%c\0",a[i]);
    }
    else{
      sprintf( tmp, "(%s %c %s)\0", s_stack[s_sp-2],a[i],s_stack[s_sp-1] );
      sprintf( s_stack[s_sp-2], "%s", tmp);
      s_sp--;
    }
  }
  strcpy(b,s_stack[0]);
}
/*メイン関数*/
main()
{
  char op[5] = "+-*/\0";
  char a[STR_LEN];
  char b[STR_LEN];
  char result[RANGE][STR_LEN];
  int i,j,k,l;
  double ans;
  for(i = 0;i < 4;i++){
    for(j = 0;j < 4;j++){
      for(k = 0;k < 4;k++){
        sprintf(a,"44%c4%c4%c\0",op[i],op[j],op[k]); //逆ポーランド記法の式を生成
        ans = calc(a,7); //演算結果を得る
        for(l = 0;l< RANGE;l++){ //0からRANGEの間にある整数と等しいかどうかを調べる
          if(ans == (double)l){
            toInfix(a,7,b); //等しい場合は中間記法に変換
            strcpy(result[l],b); //resultに式を記録する
          }
        }
        sprintf(a,"44%c44%c%c\0",op[i],op[j],op[k]);
        ans = calc(a,7);
        for(l = 0;l< RANGE;l++){
          if(ans == (double)l){
            toInfix(a,7,b);
            strcpy(result[l],b);
          }
        }
        sprintf(a,"444%c%c4%c\0",op[i],op[j],op[k]);
        ans = calc(a,7);
        for(l = 0;l< RANGE;l++){
          if(ans == (double)l){
            toInfix(a,7,b);
            strcpy(result[l],b);
          }
        }
        sprintf(a,"444%c4%c%c\0",op[i],op[j],op[k]);
        ans = calc(a,7);
        for(l = 0;l< RANGE;l++){
          if(ans == (double)l){
            toInfix(a,7,b);
            strcpy(result[l],b);
          }
        }
        sprintf(a,"4444%c%c%c\0",op[i],op[j],op[k]);
        ans = calc(a,7);
        for(l = 0;l< RANGE;l++){
          if(ans == (double)l){
            toInfix(a,7,b);
            strcpy(result[l],b);
          }
        }
      }
    }
  }
  /*結果表示*/
  for(i=0;i<RANGE;i++){
    printf("%d = ",i);
    puts(result[i]);
  }
  return 0;
}
