'PHP rotate matrix counter-clockwise
I am solving a larger problem and at one step I need to rotate a 2D array counter-clockwise.
So if I have this matrix:
1 2 3 4
1 2 3 4
3 4 5 6
3 4 5 6
After the rotation it will be:
4 4 6 6
3 3 5 5
2 2 4 4
1 1 3 3
I have found a solution to rotate it clockwise:
<?php
$a = array(array(1,2,3,4),array(5,6,7,8),array(9,0,1,2),array(3,4,5,6));
$b = array(); //result
while(count($a)>0)
{
$b[count($a[0])-1][] = array_shift($a[0]);
if (count($a[0])==0)
{
array_shift($a);
}
}
?>
The thing is that this has to work even when a
is uni-dimensional or has only one element.
So, 1 2 3 4
will become:
4
3
2
1
Solution 1:[1]
$b = call_user_func_array(
'array_map',
array(-1 => null) + array_map('array_reverse', $a)
);
I'll leave it as an exercise for the reader to figure out how it works.
Solution 2:[2]
Most concisely, transpose the array then reverse the first level. Done.
Code: (Demo)
$a = [[1,2,3,4],[1,2,3,4],[3,4,5,6],[3,4,5,6]];
var_export(array_reverse(array_map(null, ...$a)));
This approach will fail if the input array is a rectangular matrix with only one row. This is due to how array_map()
behaves with a null
callback.
To stabilize the transposition, use nested loops (Demo)
$result = [];
foreach ($array as $row) {
foreach ($row as $i => $v) {
$result[$i][] = $v;
}
}
var_export(array_reverse($result));
Or (Demo)
$result = [];
foreach ($array as $row) {
foreach (array_reverse($row) as $i => $v) {
$result[$i][] = $v;
}
}
var_export($result);
Solution 3:[3]
Here's a solution that does both clockwise and counter-clockwise matrix rotation:
$a = array(array(1,2,3,4),array(5,6,7,8),array(9,0,1,2),array(3,4,5,6));
$b = $a; //result
$clockwise = false; // toggle for clockwise / counter-clockwise
$rows = count($a);
$columns = ($rows > 0) ? count($a[0]) : 0;
for ($y = 0; $y < $rows; $y++) {
for ($x = 0; $x < $columns; $x++) {
$newX = $clockwise ? $y : ($rows - 1) - $y;
$newY = $clockwise ? ($columns - 1) - $x : $x;
$b[$newX][$newY] = $a[$x][$y];
}
}
Solution 4:[4]
Here is a recursive way:
$m = array();
$m[0] = array('a', 'b', 'c');
$m[1] = array('d', 'e', 'f');
$m[2] = array('g', 'h', 'i');
$newMatrix = array();
function rotateMatrix($m, $i = 0, &$newMatrix)
{
foreach ($m as $chunk) {
$newChunk[] = $chunk[$i];
}
$newMatrix[] = array_reverse($newChunk);
$i++;
if ($i < count($m)) {
rotateMatrix($m, $i, $newMatrix);
}
}
rotateMatrix($m, 0, $newMatrix);
echo '<pre>';
var_dump($newMatrix);
echo '<pre>';
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | salathe |
Solution 2 | |
Solution 3 | Filippos Karapetis |
Solution 4 | taxicala |