Q:

PHP for loop within for loop. Trying to sum multiple array columns to get combinations

i am trying to loop through a two-dimensional array and take a sum of the combinations of the columns automatically.
Suppose i have an array called $a with 4 columns:0,1,2,3,
$a=array();
$a[0][0]=1;
$a[0][1]=3;
$a[0][2]=5;

$a[1][0]=10;
$a[1][1]=2;  
$a[1][2]=5;
$a[1][3]=7;

$a[2][0]=9;
$a[2][1]=8;  
$a[2][2]=9;
$a[2][3]=8;

$a[3][0]=9;
$a[3][1]=8;  
$a[3][2]=9;
$a[3][3]=8;
$a[3][4]=1;

And i am trying to sum over all of the combinations of the columns like sum(0,0;1,0;2;0,3;0) etc using this code
for($i=0;$i<count($a[0]);$i++){
for($l=0;$l<count($a[1]);$l++){ 
for($s=0;$s<count($a[2]);$s++){ 
for($m=0;$m<count($a[3]);$m++){
 echo $sum[]= $a[0][$i]+$a[1][$l]+$a[2][$s]+$a[3][$m]; 
 echo $sum;
  echo "<br>";
   } 
   } 
 }
 }

 ?>

And the code works, the problem is that i am doing these for loops manually, there must be some way in which i can simplify this by somehow inserting the count of the number of columns?
I tried something like
$numberofcolumns=4; 

for($n=0;$n<$numberofcolumns;$n++){
for($i=0;$i<count($a[$n]);$i++){
for($m=0;$m<count($a[$n+1]);$m++){
echo $sums[]= $a[$n][$i]+$a[$n+1][$m];
}
}
}

but that doesn't work, there must be some way to simplify the for loops so that i don't have to manually type in the for loops each column
anybody have a clue?

A:

You can use recursion, or just straight nested loops for this, but when working with combinations or permutations, the total number of possibilities can explode and become a huge number, consuming lots of memory to the point where you just cant run the code. Using an iterator is a nice way to trade cpu efficiency for memory efficiency. Here's an iterator I wrote.
class CartesianProductIterator implements Iterator {
    protected $iterators;

    function __construct(array $iters) {
        $this->iterators = $iters;
    }

    function rewind() {
        foreach ($this->iterators as $it) {
            $it->rewind();
        }
    }

    function current() {
        $values = array();
        foreach ($this->iterators as $it) {
            $values[] = $it->current();
        }
        return $values;
    }

    function key() {
        return null;
    }

    function next() {
        /*      
        loop them in reverse, but exclude first
        why? example, odometer: 55199
        you always check the rightmost digit first to see if incrementing it would roll it over and need to be "rewound" to 0, 
        which causes the digit to the left to increase as well, which may also cause it to roll over as well, and so on...
        looping in reverse operates from right column to the left.
        we dont rewind the first column because if the leftmost column is on its last element and needs to roll over
        then this iterator has reached its end, and so rewind() needs to be explicitly called 
        */
        for ($i = count($this->iterators) - 1; $i > 0; --$i) {
            $it = $this->iterators[$i];
            $it->next();
            if ($it->valid()) {
                // were done advancing because we found a column that didnt roll over
                return;
            } else {
                $it->rewind();
            }
        }

        //if execution reached here, then all of the columns have rolled over, so we must attempt to roll over the left most column
        $this->iterators[0]->next();
    }

    function valid() {
        return $this->iterators[0]->valid();
    }
}

Then use it as 
$iterators = array();
foreach ($a as $columnNumber => $values) {
    $iterators[] = new ArrayIterator($values);
}
foreach (new CartesianProductIterator($iterators) as $combo) {
    // combo has 1 value from each of the ArrayIterators we instantiated
    printf("summing %s = %d\n", join('+', $combo), array_sum($combo));
}

heres a demo http://codepad.org/UasdgvWf

