/*
 * This file has been developed at the University of Munich, Chair for Programming & Software Engineering.
 * 
 * This file is licensed under the Eclipse Public License (EPL) 1.0
 * 
 */
package eu.uml4soa.utbm.u2m;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class MathUtil {


	/**
	 * Returns the power set from the given set by using a binary counter
	 * Example: S = {a,b,c} P(S) = {[], [c], [b], [b, c], [a], [a, c], [a, b],
	 * [a, b, c]}
	 * 
	 * @param set String[]
	 * @return LinkedHashSet
	 */
	public static Set<Set<String>> powerset(Set<Set<String>> set) {

		// convert to list.
		List<Set<String>> list= new ArrayList<Set<String>>(set);

		// create the empty power set
		Set<Set<String>> power= new LinkedHashSet<Set<String>>();

		// get the number of elements in the set
		int elements= list.size();

		// the number of members of a power set is 2^n
		int powerElements= (int) Math.pow(2, elements);

		// run a binary counter for the number of power elements
		for (int i= 0; i < powerElements; i++) {

			// convert the binary number to a string containing n digits
			String binary= intToBinary(i, elements);

			// create a new set
			Set<String> innerSet= new LinkedHashSet<String>();

			// convert each digit in the current binary number to the
			// corresponding element
			// in the given set
			boolean gotOne= false;
			for (int j= 0; j < binary.length(); j++) {
				if (binary.charAt(j) == '1') {
					innerSet.addAll(list.get(j));
					gotOne= true;
				}
			}

			// add the new set to the power set
			// do not add the empty set resulting from this algorithm; only if
			// it was really produced by an empty input set.
			if (gotOne)
				power.add(innerSet);
		}

		return power;
	}

	/**
	 * Converts the given integer to a String representing a binary number with
	 * the specified number of digits For example when using 4 digits the binary
	 * 1 is 0001
	 * 
	 * @param binary int
	 * @param digits int
	 * @return String
	 */
	private static String intToBinary(int binary, int digits) {

		String temp= Integer.toBinaryString(binary);
		int foundDigits= temp.length();
		String returner= temp;
		for (int i= foundDigits; i < digits; i++) {
			returner= "0" + returner;
		}

		return returner;
	}
}
