Place +,-, nothing between 1, 2, …, 9 (in this order) whose sum is 100

I am trying to solve a programming problem and I see the size of program has increased a bit while I keep coding. I found this problem here.
Here is the problem:
Write a program that outputs all possibilities to put + or - or nothing between the numbers 1, 2, ..., 9 (in this order) such that the result is always 100. For example: 1 + 2 + 34 – 5 + 67 – 8 + 9 = 100.
I coded it in Java.
Here is the complete program.
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * Write a program that outputs all possibilities to put + or -
 * or nothing between the numbers 1, 2, ..., 9 (in this order)
 * such that the result is always 100. For example: 1 + 2 + 34 – 5 + 67 – 8 + 9 = 100.
 */
/**
 * @author srk
 */

public class Problem5 {

    private final int START_INDEX = 0;
    private final String LEFT_SQUARE_BRACE = "[";
    private final String RIGHT_SQUARE_BRACE = "]";
    private final String SPLIT_STRING_REGEX = ",";
    private final String STRING_SUFFIX = ",";
    private final List<String> OPERATIONS = Arrays.asList("+", "-", "");

    public static void main(String[] args) {
        Problem5 problem5 = new Problem5();

        List<Integer> oneToNine = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        int resultantSum = 100;
        /* Step 1: Break it into functions */
        LinkedHashMap<String, List<StringBuilder>> fBreakUp = problem5
                .breakIntoFunctions(new ArrayList<>(oneToNine),
                        new LinkedHashMap<String, List<StringBuilder>>());
        /* Step2: Resolve each function from bottom up */
        problem5.workFromBottomUp(problem5.fBreakUpKeysFrmTail(fBreakUp),
                fBreakUp);
        /*
         * Step3: Evaluate all the combinations and fetch only those, whose sum
         * is 100
         */
        List<StringBuilder> allcombinations = fBreakUp.get(problem5
                .getfunction(oneToNine));
        System.out.println("Probable combinations -> " + allcombinations.size());
        List<String> specCombinations = problem5.getSpecCombinations(
                allcombinations, resultantSum);
        problem5.printResult(specCombinations);
    }

    private void printResult(List<String> specCombinations) {
        for (String combination : specCombinations) {
            System.out.println(combination);
        }
        System.out.println("Total combinations " + specCombinations.size());

    }

    private List<String> getSpecCombinations(
            List<StringBuilder> allcombinations, int resultantSum) {
        List<String> finalCombi = new ArrayList<>();

        for (StringBuilder csv : allcombinations) {
            for (String thisCombi : csv.toString().split(SPLIT_STRING_REGEX)) {
                if (findSum(thisCombi).compareTo(
                        BigInteger.valueOf(resultantSum)) == 0) {
                    finalCombi.add(thisCombi);
                }
            }
        }
        return finalCombi;

    }

    private static BigInteger findSum(String input) {
        /* Step1 : Split with + */
        String[] positives = input.split("[+]+");
        List<BigInteger> ListAfterExpEval = new ArrayList<>();
        for (String thisPosExp : positives) {
            BigInteger expValue = BigInteger.ZERO;
            if (thisPosExp.contains("-")) {
                /* Split with -, if it has */
                String[] negatives = thisPosExp.split("[-]+");
                for (String thisNegExp : negatives) {
                    /* Covert String to BigInteger */
                    BigInteger thisNumber = new BigInteger(thisNegExp);
                    if (expValue == BigInteger.ZERO) {
                        expValue = thisNumber;
                    } else {
                        expValue = expValue.subtract(thisNumber);
                    }
                }
                ListAfterExpEval.add(expValue);
            } else {
                /* could be a number */
                ListAfterExpEval.add(new BigInteger(thisPosExp));
            }

        }
        BigInteger finalSum = BigInteger.ZERO;
        for (BigInteger thisNum : ListAfterExpEval) {
            if (finalSum == BigInteger.ZERO) {
                finalSum = thisNum;
            } else {
                finalSum = finalSum.add(thisNum);
            }

        }
        return finalSum;
    }

    private void workFromBottomUp(List<String> fBreakUpKeys,
            LinkedHashMap<String, List<StringBuilder>> fBreakUp) {
        String tailKeyInFBreakUp = fBreakUpKeys.remove(START_INDEX);
        Iterator<String> fBreakUpKeysItr = fBreakUpKeys.iterator();
        String keyBeforeTail;
        while (fBreakUpKeysItr.hasNext()) {
            keyBeforeTail = fBreakUpKeysItr.next();
            fBreakUpKeysItr.remove();
            tailKeyInFBreakUp = resolveFunctions(tailKeyInFBreakUp,
                    keyBeforeTail, fBreakUp);
        }

    }

    private String resolveFunctions(String tailKeyInFBreakUp,
            String keyBeforeTail,
            LinkedHashMap<String, List<StringBuilder>> fBreakUp) {
        List<StringBuilder> fValToBeSubstituted = fBreakUp
                .get(tailKeyInFBreakUp);
        List<StringBuilder> fValsToBeResolved = fBreakUp.get(keyBeforeTail);
        for (StringBuilder fValToBeResolved : fValsToBeResolved) {
            int indexOfF = fValToBeResolved.indexOf(tailKeyInFBreakUp);
            if (indexOfF != -1) {
                fValToBeResolved.replace(indexOfF, fValToBeResolved.length(),
                        fValToBeSubstituted.toString());
                fValToBeResolved.replace(START_INDEX,
                        fValToBeResolved.length(),
                        cartesianProduct(fValToBeResolved));
            }
        }
        fBreakUp.remove(tailKeyInFBreakUp);
        return keyBeforeTail;
    }

    private String cartesianProduct(StringBuilder fValToBeResolved) {
        StringBuilder localSb = new StringBuilder();
        int indexOfLeftSqBrace = fValToBeResolved.indexOf(LEFT_SQUARE_BRACE);
        int indexOfRightSqBrace = fValToBeResolved.indexOf(RIGHT_SQUARE_BRACE);
        String prefix = fValToBeResolved.substring(START_INDEX,
                indexOfLeftSqBrace);
        List<String> resolvedVals = Arrays.asList(fValToBeResolved.substring(
                indexOfLeftSqBrace + 1, indexOfRightSqBrace).split(
                SPLIT_STRING_REGEX));
        for (String val : resolvedVals) {
            localSb.append(prefix.trim() + val.trim());
            if (resolvedVals.indexOf(val) != resolvedVals.size() - 1) {
                localSb.append(STRING_SUFFIX);
            }
        }
        return localSb.toString();
    }

    private List<String> fBreakUpKeysFrmTail(
            LinkedHashMap<String, List<StringBuilder>> fBreakUp) {
        List<String> functionsBreakUpKeys = new ArrayList<>(fBreakUp.keySet());
        Collections.reverse(functionsBreakUpKeys);
        return functionsBreakUpKeys;
    }

    private LinkedHashMap<String, List<StringBuilder>> breakIntoFunctions(
            List<Integer> workList,
            LinkedHashMap<String, List<StringBuilder>> fBreakUp) {

        String function = getfunction(workList);
        String head = getHeadAndRemoveit(workList);

        boolean workListSizeIsOne = workList.size() == 1 ? true : false;
        ArrayList<StringBuilder> breakDownValues = new ArrayList<>();

        for (String operation : OPERATIONS) {
            StringBuilder sb = new StringBuilder();
            if (!(workListSizeIsOne ? breakDownValues.add(sb.append(head
                    + operation + workList.get(START_INDEX))) : breakDownValues
                    .add(sb.append(head + operation + getfunction(workList)))))
                break;

        }
        fBreakUp.put(function, breakDownValues);

        if (!workList.isEmpty() && !workListSizeIsOne)
            breakIntoFunctions(workList, fBreakUp);

        return fBreakUp;
    }

    private String getHeadAndRemoveit(List<Integer> workList) {
        Integer headElement = workList.get(START_INDEX);
        workList.remove(headElement);
        return String.valueOf(headElement);
    }

    private String getfunction(List<Integer> list) {
        StringBuilder sb = new StringBuilder("f(");
        for (Integer integ : list) {
            sb.append(integ);
        }
        return sb.append(")").toString();
    }

}
What are the points, where it could be improved and optimized?

Комментарии

Популярные сообщения из этого блога

Skipping acquire of configured file 'contrib/binary-i386/Packages' as repository … doesn't support architecture 'i386'

Connection string for MariaDB using ODBC

Celery like system based on django channels