#include <stdio.h>
#include <string.h>
#define NUM 4
/* 外部変数の定義 */
int n_ans=0;       /* 解の数をカウント        */
char ans[10000][255];  /* 解を保存しておく(10000個まで) */
/* 数をあらわす構造体 (分数の形で定義) */
struct bunsu
{
  int bunshi, bunbo;  /* 分子，分母 */
  int pre_cul;       /* 一つ前に何の演算をしたか(0:なし  1:＋or−  2:×or÷) */
  char form[255];    /* その数を作った際の計算式 */
};
/* 同じ解が存在するかできるだけチェックする関数 */
/*    返す値 0:同じ解がない  1:同じ解があった */
int ans_check(char form[])
{
  int i;
  for (i=0; i<n_ans; i++) {
    if (strcmp(ans[i], form)==0) return 1;
    if ((strstr(form, "×")==NULL) && (strstr(form, "÷")==NULL) && (n_ans!=0)) return 1;
  }
  if (n_ans<10000) {  /* 10000個までカウント */
    strcpy(ans[n_ans], form);
    n_ans++;
  }
  if (n_ans==1) {  /* 初めて解が出て来た時 */
    printf(" 10を作ることが出来ます．\n");
    printf(" 以下にその解を表示します．\n\n");
  }
  return 0;
}
/* 再帰により実際に全ての組合せを計算してみて  */
/* 10になるか確かめる関数 (事実上のメイン関数) */
void Calculate(struct bunsu * data,int nums)
{
  if (nums == 1){  /* 計算がおわった場合 */
    /* 計算結果が10になるかチェック */
    if (((double)data[0].bunshi / data[0].bunbo) == 10.0) {
      if (ans_check(data[0].form)==0) {
        if (n_ans%10==0) printf("\n");
        printf("%7d  ", data[0].bunshi / data[0].bunbo);
        printf("->  %s\n", data[0].form);
      }
    }
  }
  else {  /* まだ計算がおわってない場合 */
    /* この段階で計算をする２つを決める*/
    struct bunsu newdata[NUM];
    int i,j,k,l;
    for (i=0; i<nums;i++) {
      for (j=1; j<nums; j++) {
        if (i==j) continue;
        for (k=l=0;k<nums;k++) {
          if (k!=i && k!=j) {
            newdata[l] = data[k];
            l++;
          }
        }
        /* ここから実際に data[i], data[j]について計算していく */
        /* 足し算(data[i]＋data[j]) */
        newdata[l].bunbo=data[i].bunbo*data[j].bunbo;
        newdata[l].bunshi=data[i].bunshi*data[j].bunbo
        +data[j].bunshi*data[i].bunbo;
        newdata[l].pre_cul=1;
        sprintf(newdata[l].form, "%s ＋ %s", data[i].form, data[j].form);
        Calculate(newdata,nums-1);  /* 再帰を用いて次の段階の計算へ */
        /* 引き算(data[i]−data[j]) */
        newdata[l].bunbo=data[i].bunbo*data[j].bunbo;
        newdata[l].bunshi=data[i].bunshi*data[j].bunbo
        -data[j].bunshi*data[i].bunbo;
        newdata[l].pre_cul=1;
        if (data[j].pre_cul!=1)
        sprintf(newdata[l].form, "%s − %s", data[i].form, data[j].form);
        else
        sprintf(newdata[l].form, "%s − (%s)", data[i].form, data[j].form);
        Calculate(newdata,nums-1);  /* 再帰を用いて次の段階の計算へ */
        /* 引き算(data[j]−data[i]) */
        newdata[l].bunbo=data[i].bunbo*data[j].bunbo;
        newdata[l].bunshi=data[j].bunshi*data[i].bunbo
        -data[i].bunshi*data[j].bunbo;
        newdata[l].pre_cul=1;
        if (data[i].pre_cul!=1)
        sprintf(newdata[l].form, "%s − %s", data[j].form, data[i].form);
        else
        sprintf(newdata[l].form, "%s − (%s)", data[j].form, data[i].form);
        Calculate(newdata,nums-1);  /* 再帰を用いて次の段階の計算へ */
        /* 掛け算(data[i]×data[j]) */
        newdata[l].bunbo=data[i].bunbo*data[j].bunbo;
        newdata[l].bunshi=data[i].bunshi*data[j].bunshi;
        newdata[l].pre_cul=2;
        if (data[i].pre_cul!=1)
        sprintf(newdata[l].form, "%s", data[i].form);
        else
        sprintf(newdata[l].form, "(%s)", data[i].form);
        if (data[j].pre_cul!=1)
        sprintf(newdata[l].form, "%s × %s",
        newdata[l].form, data[j].form);
        else
        sprintf(newdata[l].form, "%s × (%s)",
        newdata[l].form, data[j].form);
        Calculate(newdata,nums-1);  /* 再帰を用いて次の段階の計算へ */
        /* 割り算(data[i]÷data[j]) */
        if ((data[j].bunshi!=0) &&
        ((double)data[j].bunshi/data[j].bunbo!=1.0)){
          /* 0で割るのを防ぐため */
          /* 1で割るのは1をかけるのと同じため*/
          newdata[l].bunbo=data[i].bunbo*data[j].bunshi;
          newdata[l].bunshi=data[i].bunshi*data[j].bunbo;
          newdata[l].pre_cul=2;
          if (data[i].pre_cul!=1)
          sprintf(newdata[l].form, "%s", data[i].form);
          else
          sprintf(newdata[l].form, "(%s)", data[i].form);
          if (data[j].pre_cul==0)
          sprintf(newdata[l].form, "%s ÷ %s",
          newdata[l].form, data[j].form);
          else
          sprintf(newdata[l].form, "%s ÷ (%s)",
          newdata[l].form, data[j].form);
          Calculate(newdata,nums-1);  /* 再帰を用いて次の段階の計算へ */
        }
        /* 割り算(data[j]÷data[i]) */
        if ((data[i].bunshi!=0) &&
        ((double)data[i].bunshi/data[i].bunbo!=1.0)){
          /* 0で割るのを防ぐため */
          /* 1で割るのは1をかけるのと同じため*/
          newdata[l].bunbo=data[j].bunbo*data[i].bunshi;
          newdata[l].bunshi=data[j].bunshi*data[i].bunbo;
          newdata[l].pre_cul=2;
          if (data[j].pre_cul!=1)
          sprintf(newdata[l].form, "%s", data[j].form);
          else
          sprintf(newdata[l].form, "(%s)", data[j].form);
          if (data[i].pre_cul==0)
          sprintf(newdata[l].form, "%s ÷ %s",
          newdata[l].form, data[i].form);
          else
          sprintf(newdata[l].form, "%s ÷ (%s)",
          newdata[l].form, data[i].form);
          Calculate(newdata,nums-1);  /* 再帰を用いて次の段階の計算へ */
        }
      }
    }
  }
}
/* メイン関数 */
main()
{
  int i,tmp;
  struct bunsu data[NUM];
  /* データの入力 */
  printf("数字を入力してください．(-1で終了)\n");
  for (i=0;i<NUM;i++) {
    printf(" %d個目=?  ",i+1);
    scanf("%d",&tmp);
    data[i].bunshi=tmp;
    data[i].bunbo=1;
    data[i].pre_cul=0;
    sprintf(data[i].form, "%d", tmp);
  }
  /* 実際の計算と結果の表示 */
  printf("\n<< Results >>\n");
  Calculate(data,NUM);
  printf("\n");
  if (n_ans==0) printf(" 10を作ることは出来ませんでした．\n\n");
}
