Search code examples
javabooleansubsetcombinations

java List with all combinations of 8 booleans


Let's say I pass in 3 trues and 5 falses, how can I code the getAllCombos method to return a List that includes:

  • A 1 SampleForSO object with the 3 chosen
  • The 3 "Three Choose Two" combinations
  • The 3 "Three Choose One" combinations
  • The 1 SampleForSO object with none chosen

So I'd return a List with:

  • SampleForSO(T, T, T, F, F, F, F, F)
  • SampleForSO(T, T, F, F, F, F, F, F)
  • SampleForSO(T, F, T, F, F, F, F, F)
  • SampleForSO(F, T, T, F, F, F, F, F)
  • SampleForSO(T, T, F, F, F, F, F, F)
  • SampleForSO(F, T, T, F, F, F, F, F)
  • SampleForSO(T, F, T, F, F, F, F, F)
  • SampleForSO(F, F, F, F, F, F, F, F)

public class SampleForSO {

private boolean b0;
private boolean b1;
private boolean b2;
private boolean b3;
private boolean b4;
private boolean b5;
private boolean b6;
private boolean b7;

public SampleForSO(boolean b0, boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7) {
    this.b0 = b0;
    this.b1 = b1;
    this.b2 = b2;
    this.b3 = b3;
    this.b4 = b4;
    this.b5 = b5;
    this.b6 = b6;
    this.b7 = b7;
}

public boolean equals(Object o) {
    if(o instanceof SampleForSO) {
        SampleForSO outer = (SampleForSO) o;
        return outer.b0 == this.b0 && outer.b1 == this.b1 && outer.b2 == this.b2 && outer.b3 == this.b3 && outer.b4 == this.b4 && outer.b5 == this.b5 && outer.b6 == this.b6 && outer.b7 == this.b7;
    }
    return false;
    
}

public static List<SampleForSO> getAllCombos(boolean b0, boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7){
    // How to get all the combos?
    return new ArrayList<SampleForSO>();
}

}


Here's a JUnit test that would show green if that method worked:
public class SampleForSOTest {

    public SampleForSOTest() {
        super();
    }
    
    @Test
    public void testGetAllCombinations() throws Exception {
        
        // 3 true, 5 false, but need this to work for all possibilities
        boolean b0_ = true;
        boolean b1_ = true;
        boolean b2_ = true;
        boolean b3_ = false;
        boolean b4_ = false;
        boolean b5_ = false;
        boolean b6_ = false;
        boolean b7_ = false;

        int numCombosWithAllThree = 1;
        int numCombosWithTwo = 3;
        int numCombosWithOne = 3;
        int numCombosWithZero = 1;

        int expectedSize = numCombosWithAllThree + numCombosWithTwo + numCombosWithOne + numCombosWithZero;
        
        List<SampleForSO> allCombos = SampleForSO.getAllCombos(b0_, b1_, b2_, b3_, b4_, b5_, b6_, b7_);

        assertEquals(expectedSize, allCombos.size());
    }

    

}

The combos I'd want would be:

  • b0, b1, b2 all true, all else false
  • b0 b1 true, all else false
  • b1 b2 true, all else false
  • b2 b0 true, all else false
  • b0 true, all else false
  • b1 true, all else false
  • b2 true, all else false
  • all false

Solution

  • Following Code generates all combinations

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class Main {
    
      public static List<List<Boolean>> generateAllCombinations(List<Boolean> input) {
        var combinations = new ArrayList<List<Boolean>>();
        if (input.isEmpty()) {
          return combinations;
        }
    
        // add combination seed
        combinations.add(new ArrayList<>());
        for (var inputIndexValue : input) {
          var nextCombinations= new ArrayList<List<Boolean>>();
    
          for (var indexCombination : combinations) {
              
            if (inputIndexValue) {
               // true is only valid if inputIndexValue is true
              var newCombination = new ArrayList<>(indexCombination);
              newCombination.add(true);
              nextCombinations.add(newCombination);
            }
            
            // false is always a valid value
            var newCombination = new ArrayList<>(indexCombination);
            newCombination.add(false);
            nextCombinations.add(newCombination);
          }
    
          combinations = nextCombinations;
        }
    
        return combinations;
      }
    
      public static void main(String[] args) {
        var input = List.of(true, true, true, false, false, false, false, false);
        var allCombinations = generateAllCombinations(input);
        for (var combination : allCombinations) {
          System.out.println(combination);
        }
      }
    }