/**
* Generate all ways to write a positive integer n
* as a sum of positive integers (integer partitions).
*
* Example for n = 5:
* [
* [5],
* [4, 1],
* [3, 2],
* [3, 1, 1],
* [2, 2, 1],
* [2, 1, 1, 1],
* [1, 1, 1, 1, 1]
* ]
*/
/**
* Returns all partitions of a positive integer.
*
* @param int $n The number to partition.
* @return array Array of partitions.
*/
function partitions(int $n): array {
$results = [];
/**
* Backtracking helper.
*
* @param int $remaining How much is left to reach n.
* @param int $max Maximum allowed next number.
* @param array $current Current partial partition.
*/
$backtrack = function($remaining, $max, $current) use (&$results, &$backtrack) {
// If nothing remains, we found a valid partition
if ($remaining === 0) {
$results[] = $current;
return;
}
// Try next numbers from max down to 1
for ($next = min($remaining, $max); $next >= 1; $next--) {
$newCurrent = $current;
$newCurrent[] = $next; // choose
$backtrack($remaining - $next, $next, $newCurrent); // explore
}
};
$backtrack($n, $n, []);
return $results;
}
// Run the program:
$result = partitions(5);
print_r($result);
/*
run:
Array
(
[0] => Array
(
[0] => 5
)
[1] => Array
(
[0] => 4
[1] => 1
)
[2] => Array
(
[0] => 3
[1] => 2
)
[3] => Array
(
[0] => 3
[1] => 1
[2] => 1
)
[4] => Array
(
[0] => 2
[1] => 2
[2] => 1
)
[5] => Array
(
[0] => 2
[1] => 1
[2] => 1
[3] => 1
)
[6] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
[4] => 1
)
)
*/