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 C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AOJ
{
    class Program
    {
        static int Add(int lhs, int rhs)
        {
            return lhs + rhs;
        }
        static int Sub(int lhs, int rhs)
        {
            return lhs - rhs;
        }
        static int Mul(int lhs, int rhs)
        {
            return lhs * rhs;
        }

        static private Func<int, int, int>[] ops = { Add, Sub, Mul };
        private static string[] opsString = {"+", "-", "*"};

        static bool OpsA(int[] nums)
        {
            for(int i = 0; i < 3; i++)
            for(int j = 0; j < 3; j++)
            for(int k = 0; k < 3; k++)
            {
                if (ops[k](ops[j](ops[i](nums[0], nums[1]), nums[2]), nums[3]) == 10)
                {
                    Console.WriteLine("(({0} {4} {1}) {5} {2}) {6} {3}", nums[0], nums[1], nums[2], nums[3], opsString[i], opsString[j], opsString[k]);
                    return true;
                }
            }
            return false;
        }

        static bool OpsB(int[] nums)
        {
            for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
            for (int k = 0; k < 3; k++)
            {
                if (ops[k](ops[i](nums[0], nums[1]), ops[j](nums[2], nums[3])) == 10)
                {
                    Console.WriteLine("({0} {4} {1}) {6} ({2} {5} {3})", nums[0], nums[1], nums[2], nums[3], opsString[i], opsString[j], opsString[k]);
                    return true;
                }
            }
            return false;
        }

        static void Main(string[] args)
        {
            string line;
            while((line = Console.ReadLine()) != null)
            {
                if (line == "0 0 0 0") break;
                var d = line.Split(' ').Select(int.Parse).ToArray();
                if (!Permutation(d).Any(ints => OpsA(ints) || OpsB(ints)))
                    Console.WriteLine("0");
            }
        }

        static IEnumerable<int[]> Permutation(int[] source)
        {
            var used = new bool[source.Length];
            for (int i = 0; i < source.Length; i++)
            for (int j = 0; j < source.Length - 1; j++)
            for (int k = 0; k < source.Length - 2; k++)
            for (int l = 0; l < source.Length - 3; l++)
            {
                Array.Clear(used, 0, used.Length);
                var ints = new int[source.Length];
                GetValue(source, used, i, ints, 0);
                GetValue(source, used, j, ints, 1);
                GetValue(source, used, k, ints, 2);
                GetValue(source, used, l, ints, 3);
                yield return ints;
            }
        }

        private static void GetValue(int[] source, bool[] used, int j, int[] ints, int level)
        {
            for(int i = 0, index = -1; i < source.Length; i++)
            {
                if (!used[i]) index++;
                if (index != j) continue;
                ints[level] = source[i];
                used[i] = true;
                break;
            }
        }
    }
}