Problem:
式

与えられた 4 つの 1 から 9 の整数を使って、答えが 10 になる式をつくります。
4 つの整数 a, b, c, d を入力したとき、下記の条件に従い、答えが 10 になる式を出力するプログラムを作成してください。また、答えが複数ある時は、最初に見つかった答えだけを出力するものとします。答えがない時は、0 と出力してください。

演算子として、加算 (+)、減算 (-)、乗算 (*) だけを使います。除算 (/) は使いません。使用できる演算子は３個です。

数を4つとも使わなければいけません。

4つの数の順番は自由に入れ換えてかまいません。

カッコを使ってもかまいません。使用できるカッコは３組（６個）以下です。

Input

複数のデータセットが与えられます。各データセットの形式は以下のとおり：

a b c d

入力は４つの 0 で終了します。データセットの数は 40 を超えません。

Output

各データセットについて、与えられた 4 つの整数と上記の演算記号およびカッコを組み合わせて値が 10 となる式または 0 を１行に出力してください。式の文字列が 1024 文字を超えてはいけません。

Sample Input

8 7 9 9
4 4 4 4
5 5 7 5
0 0 0 0

Output for the Sample Input

((9 * (9 - 7)) - 8)
0
((7 * 5) - (5 * 5))

Solution in Ruby (judge verdict: Accepted)

def calc_rev_polish(exp, stack)
  # puts "#{exp} #{stack}"

  if exp.empty?
    return stack.pop if stack.size == 1
    return nil
  end

  val = exp.shift
  return nil if val.nil?
  if val.class == Fixnum
    stack.push(val)
    return calc_rev_polish(exp, stack)
  end

  a = stack.pop
  b = stack.pop
  return nil if b.nil?
  if val == "+"
    stack.push(b+a)
  elsif val == "-"
    stack.push(b-a)
  else
    stack.push(b*a)
  end
  return calc_rev_polish(exp, stack)
    
end

def find_prev_term(exp, pos)
  par_count = 0
  pos.downto(0){|p|
    if p <= 0
      return p
    end

    if exp[p].class == Fixnum && par_count == 0
      return p
    end

    if exp[p] == ")"
      par_count += 1
    end

    if exp[p] == "("
      par_count -= 1
      if par_count == 0
        return p
      end
    end
  }

end

def rev2norm(rev)
  norm = []

  rev.each{|v|
    if v.class == Fixnum
      norm.push(v)
      next
    end

    pos1 = find_prev_term(norm, norm.size-1)
    norm.insert(pos1, v)

    pos2 = find_prev_term(norm, pos1-1)
    norm.insert(pos2, "(")
    norm.push(")")

    # p norm
  }
  return norm
end

ARGF.each{|line|
  break if line.chomp == "0 0 0 0"

  nums = line.chomp.split(/ /).map{|c| c.to_i}
  ops = " +-*".split(//)

  out = nil
  nums.permutation(4){|num_seq|
    ops.repeated_permutation(6){|ops_seq|
      exp = []
      exp << num_seq[0]
      exp << num_seq[1]
      exp << ops_seq[0]
      exp << num_seq[2]
      exp << ops_seq[1]
      exp << ops_seq[2]
      exp << num_seq[3]
      exp << ops_seq[3]
      exp << ops_seq[4]
      exp << ops_seq[5]

      # p exp
      exp.delete_if{|c| c == " "}
      exp2 = exp.dup
      if calc_rev_polish(exp, []) == 10
        out = exp2
        break
      end
    }
    break unless out.nil?
  }
  if out.nil?
    puts "0"
  else
    # p out
    puts rev2norm(out).join("")
  end
}