Last active
July 19, 2024 05:00
-
-
Save earthbound19/74fc6e2588a948f7cb608db266f7d6bb to your computer and use it in GitHub Desktop.
Processing (Java) recursive combination finder function, adapted
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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