Main Page
 The gatekeeper of reality is
 quantified imagination.

Stay notified when site changes by adding your email address:

Your Email:

Bookmark and Share
Email Notification
splitArrayIntoApproxEqualSubsets [Go Back]
Purpose
The purpose of this script is to split an array *set* into two separate array *subsets" such that when the values of one subset are added together, that value will approximately equal the added values of the other subset. Over the decades of programming I've never needed to solve such a task but I was asked about it so I provide one approach (using javascript) below.

Find the Two Approximately Equal Subsets From the Subset Question (and answer):
Given the array sequence "set": [1,6,11,5,9,3,3,4,7] split it into two approximately equal sub-arrays *subsets*; that is, when you add the values in each sub-array together then the value of subset 1 should approximately equal subset 2.
For reference, the two subsets returned should be: [3,4,5,6,7] and [1,3,9,11]

Function Logic Output:


Full Working Code You Can Copy:
<html>
<head>
<script language="javascript" type="text/javascript">
/* Declare subsets as global to simplify individual access in larger context */
var subSetOneValues = [], subSetTwoValues = [];
function splitArrayIntoApproxEqualSubsets(sequence) {
	/* Sort the sequence passed to this function */
	sequence.sort(function(a, b) {return a - b});
	/* Find working range to split array into subsets */
	var elementsTotalValue = 0, collectiveMinValue = 0, collectiveMaxValue = 0;
	for (var i = 0; i < sequence.length; i++) {
		elementsTotalValue += sequence[i];
	}
	/* Round down decimal like 1.5 to nearest whole number like 1 */
	collectiveMinValue = Math.floor(elementsTotalValue / 2);
	collectiveMaxValue = collectiveMinValue + 1;
	/* Step through array (set) */
	var subsetOneIndexes = [];
	for (var p = 0; p < sequence.length; p++) {
		var tmpSubset = [];
		var tmpCummulativeValue = 0;
		for (var s = p; s < sequence.length; s++) {
			if ((tmpCummulativeValue + sequence[s]) <= collectiveMaxValue) {
				tmpCummulativeValue += sequence[s];
				tmpSubset.push(s);
			}
			else {
				break;
			}
		}
		if (tmpCummulativeValue >= collectiveMinValue && tmpCummulativeValue <= collectiveMaxValue) {
			subsetOneIndexes = tmpSubset;
			break;
		}
		else {
			if (subsetOneIndexes.length == 0 && p == (sequence.length - 1)) {
				subsetOneIndexes.push(p);
			}
		}
	}
	/* Split array (set) into two sub-arrays (subsets) */
	for (var a = 0; a < sequence.length; a++) {
		var subSetIndexFound = false;
		for (var b = 0; b < subsetOneIndexes.length; b++) {
			if (a == subsetOneIndexes[b]) {
				subSetOneValues.push(sequence[a]);
				subSetIndexFound = true;
			}
		}
		if (subSetIndexFound == false) {
			subSetTwoValues.push(sequence[a]);
		}
	}
	var result = "Subset 1 = {" + subSetOneValues + "}\r\nSubset 2 = {" + subSetTwoValues + "}";
	return(result);
}
</script>
</head>
<body onload='javascript:document.getElementById("output").value = splitArrayIntoApproxEqualSubsets([1,6,11,5,9,3,3,4,7]);'>
	Given the array sequence "set": [1,6,11,5,9,3,3,4,7] split it into two approximately equal sub-arrays *subsets*; that is, when you add the values in each sub-array together then the value of subset 1 should approximately equal subset 2.<br />
	<span style="font-size:9pt">For reference, the two subsets returned should be: [3,4,5,6,7] and [1,3,9,11]</span>
	<br /><br />
	<strong>Function Logic Output:</strong><br />
	<textarea name="output" id="output" rows="4" cols="60"></textarea>
</body>
</html>
About Joe