import java.util.Arrays;
import java.util.*;
import java.io.Console;
import java.util.stream.Collectors;

enum Operation{
    ADDITION('+') {
	public int calc(int a, int b) throws Exception {
	    return a + b;
	}
    },
    MULTIPLICATION('x') {
	public int calc(int a, int b) throws Exception {
	    if (b == 1) {
		throw new Exception("Multiplication par 1");
	    }
	    return a * b;
	}
    },
    SOUSTRACTION('-') {
	public int calc(int a, int b) throws Exception {
	    int res = a - b;
	    if (res == b || a == b) {
		throw new Exception("Soustraction inutile");
	    }
	    return res;
	}
    },
    DIVISION('/') {
	public int calc(int a, int b) throws Exception {
	    if ( b == 1) {
		throw new Exception("Division inutile");
	    }
	    if (a % b == 0) {
		return a / b;
	    }
	    throw new Exception("Division pas entière");
	}
    }
    ;
    private char symbole;
    Operation(char leSymbole) {
	symbole = leSymbole;
    }
    public abstract int calc(int op1, int op2) throws Exception;
    public char getSymbole() {
	return symbole;
    };
}

public class Compte {
    private Console c = System.console();
    private int compte;
    private int[] plaques;

    public Compte(int leCompte, int[] lesPlaques) {
	compte = leCompte;
	plaques = new int[lesPlaques.length];
	for (int i = 0; i < lesPlaques.length; i++) {
	    plaques[i] = lesPlaques[i];
	}
	Arrays.sort(plaques);
    }

    public Compte(Compte autre, int resultat, int indicePlaque1, int indicePlaque2) {
	compte = autre.compte;
	plaques = new int[autre.plaques.length - 1];
	int indiceNouveau = 1;
	int indiceAncien = 0;
	plaques[0] = resultat;
	while (indiceNouveau < autre.plaques.length-1) {
	    if (indiceAncien == indicePlaque1 || indiceAncien == indicePlaque2) {
		indiceAncien++;
		continue;
	    }
	    plaques[indiceNouveau] = autre.plaques[indiceAncien];
	    indiceNouveau++;
	    indiceAncien++;
	}
    }
		
    public Optional<ArrayList<ArrayList<String>>> resoudreRec(ArrayList<String> trace) {
	ArrayList<ArrayList<String>> retour = new ArrayList<>();
	if (plaques[0] == compte) {
	    retour.add(trace);
	    return Optional.of(retour);
	}
	if (plaques.length == 1) {
	    return Optional.empty();
	}
	for (int i = 0; i < plaques.length -1; i++) {
	    for (int j = i+1; j < plaques.length; j++) {
		int plaque1 = plaques[i];
		int plaque2 = plaques[j];
		int plaqueMin = 0;
		int plaqueMax = 0;
		if (plaque1 < plaque2) {
		    plaqueMin = plaque1;
		    plaqueMax = plaque2;
		} else {
		    plaqueMin = plaque2;
		    plaqueMax = plaque1;
		}
		int res = 0;
		for (Operation op: Operation.values()) {
		    try {
			res = op.calc(plaqueMax, plaqueMin);
		    }
		    catch(Exception e) {
			continue;
		    }
		    Compte suite = new Compte(this, res, i, j);
		    ArrayList<String> nouvelleTrace = new ArrayList<>(trace);
		    String calcul = plaqueMax + " " + op.getSymbole() + " " + plaqueMin + " = " + res;
		    nouvelleTrace.add(calcul);
		    Optional<ArrayList<ArrayList<String>>> suiteTrace = suite.resoudreRec(nouvelleTrace);
		    if (suiteTrace.isPresent()) {
			retour.addAll(suiteTrace.get());
		    }
		}
	    }
	}
	return Optional.ofNullable(retour);
    }
				
    public void resoudre() {
	ArrayList<String> solution = new ArrayList<>();
	Optional<ArrayList<ArrayList<String>>> retour = resoudreRec(solution);
	if (retour.isPresent()) {
	    ArrayList<ArrayList<String>> solutions = retour.get();
	    int longueurLaPlusCourte = solutions
		.stream()
		.mapToInt(ArrayList::size)
		.max()
		.getAsInt();
	    String sortie = 
	    solutions.stream()
		.filter(al -> (al.size() == longueurLaPlusCourte))
		.map(s -> s.stream().collect(Collectors.joining("\n")))
		.collect(Collectors.joining("\n----------\n"));
	    System.out.println(sortie);
	} else {
	    System.out.println("Pas de solution exacte");
	}
    }


    public static void main(String... args) {
	int compte = 345;
	int[] b = {2, 3, 5, 7, 9, 75};
	Compte c = new Compte(compte, b);
	c.resoudre();
    }
}
