Skip to content

Instantly share code, notes, and snippets.

@earthbound19
Last active February 28, 2021 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earthbound19/74fc6e2588a948f7cb608db266f7d6bb to your computer and use it in GitHub Desktop.
Save earthbound19/74fc6e2588a948f7cb608db266f7d6bb to your computer and use it in GitHub Desktop.
Processing (Java) recursive combination finder function, adapted
// Processing/Java example of function that prints strings of all possible combinations of size howManyToSelect from an ArrayList<Integer>.
// Also, it constructs an ArrayList of ArrayLists of integers, with is a list of all possible combinations. Because I want this
// in Processing for my prototyping and generative art purposes. Because I am insane.
// ADDENDUM: GitHub doesn't wrap the text in the viewbox despite my just setting a toggle to do so.
// To read many comments you may need to view/copy the raw source.
// Disclaimer: I could not explain how this works. I hacked a black box function I found until it did what I want.
// This is a a recursive function (it calls itself). Adapted from: https://hmkcode.com/calculate-find-all-possible-combinations-of-an-array-using-java/
// other implementations of this or other combinatronics algorithms: https://stackoverflow.com/a/29914908/1397555 -- https://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/
// To test it, verify debug output against this, answering "no" to "Is Order important?" and "Is Repitition allowed?" : https://www.mathsisfun.com/combinatorics/combinations-permutations-calculator.html
// Global ArrayList that the function modifies:
static ArrayList<String> combinationsStrs = new ArrayList<String>();
// Global ArrayList of ArrayLists that the function modifies:
static ArrayList<ArrayList<Integer>> combinationsInts = new ArrayList<ArrayList<Integer>>();
// For practical purposes, remove/adapt parameters to this function and then remove/adapt related code in the function (for example I have no use for `String accumulated`, and I might adapt the function to require an ArrayList<ArrayList<Integer>>. Also, note that the `String accumulated` should be an empty string when passed to the function, as also should ArrayList<ArrayList<Integer>> combinationsInts be empty.
public static void combination(ArrayList<Integer> e, int howManyToSelect, String accumulated, ArrayList<Integer> combinations_too) {
// 1. stop if/when there's no point running this function.
if (e.size() < howManyToSelect)
return;
// 2. add each element in e to accumulated
if (howManyToSelect == 1) {
for (int s:e) {
// String INFO:
print("case2 accum:" + accumulated + ";s:" + s + " ");
String tmpString = accumulated + s;
combinationsStrs.add(tmpString);
// ArrayList THINGS; equivalents of the above string operations but with an ArrayList:
ArrayList<Integer> tmpIntArrayList = new ArrayList<Integer>(combinations_too);
tmpIntArrayList.add(s);
print(">"); for (int t:tmpIntArrayList ){ print(t + ";"); } print("\n");
combinationsInts.add(tmpIntArrayList);
}
}
// 3. add all elements in e to accumulated
else if (e.size() == howManyToSelect) {
ArrayList<Integer> tmpIntArrayList = new ArrayList<Integer>(combinations_too);
for (int s:e) {
accumulated += s;
tmpIntArrayList.add(s);
}
print("case3 accum:" + accumulated + " ");
String tmpString = accumulated;
combinationsStrs.add(tmpString);
print(">"); for (int t:tmpIntArrayList ){ print(t + ";"); } print("\n");
combinationsInts.add(tmpIntArrayList);
} // 4. for each element, call this function itself (recursive)
else if (e.size() > howManyToSelect) {
for (int i = 0 ; i < e.size() ; i++) {
// hacking note: because I get a *view* of a list, but not an ArrayList, via subList, convert it; re: https://stackoverflow.com/a/16644841 -- I create a temp ArrayList here by converting the return of subList:
ArrayList<Integer> tmpArrayList = new ArrayList<Integer>( e.subList( i+1, e.size() ) );
ArrayList<Integer> tmpArrayListToo = new ArrayList<Integer>(combinations_too);
tmpArrayListToo.add(e.get(i));
combination(tmpArrayList, howManyToSelect - 1, accumulated+e.get(i), tmpArrayListToo);
}
}
}
// Example code within the draw() function call of Processing because it won't work in Processing otherwise:
void draw() {
// Preparation for example function call:
ArrayList<Integer> testArrayList = new ArrayList<Integer>();
for (int i = 0; i < 6; i++) {
testArrayList.add(i);
}
String accumulationSTR = "";
ArrayList<Integer> accumulationArrayINTsList = new ArrayList<Integer>();
// Function call
combination(testArrayList, 3, accumulationSTR, accumulationArrayINTsList);
// Test print of variables modified by function call:
print("\nTest result list print from ArrayList<String> combinationsStrs:\n");
for (String s:combinationsStrs) { print(s + " "); }
print("\nTest result list print from ArrayList<Integer> combinationsInts:\n");
for (ArrayList<Integer> t:combinationsInts) {
for (int u:t) { print(u + ","); } print(" ");
}
print("\n");
// exit after only one loop of draw() :
exit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment