I have a simple array. The array length always has a square root of an integer. So 16, 25, 36 etc.
$array = array(\'1\', \'2\', \'3\', \'4\' ... \'25\');
One more PHP solution, using just for
and if
, traverses array only once
function waveSort(array $array) {
$elem = sqrt(count($array));
for($i = 0; $i < $elem; $i++) {
$multi[] = array_slice($array, $i*$elem , $elem);
}
$new = array();
$rotation = false;
for($i = 0; $i <= $elem-1; $i++) {
$k = $i;
for($j = 0; $j <= $i; $j++) {
if($rotation)
$new[] = $multi[$k][$j];
else
$new[] = $multi[$j][$k];
$k--;
}
$rotation = !$rotation;
}
for($i = $elem-1; $i > 0; $i--) {
$k = $elem - $i;
for($j = $elem-1; $j >= $elem - $i; $j--) {
if(!$rotation)
$new[] = $multi[$k][$j];
else
$new[] = $multi[$j][$k];
$k++;
}
$rotation = !$rotation;
}
return $new;
}
$array = range(1, 25);
$result = waveSort($array);
print_r($result);
$array = range(1, 36);
$result = waveSort($array);
print_r($result);
Here it is in action
Here's mine.
function waveSort(array $array) {
$dimension = pow(count($array),0.5);
if((int)$dimension != $dimension) {
throw new InvalidArgumentException();
}
$tempArray = array();
for($i = 0; $i < $dimension; $i++) {
$tempArray[] = array_slice($array,$i*$dimension,$dimension);
}
$returnArray = array();
for($i = 0; $i < $dimension * 2 -1; $i++) {
$diagonal = array();
foreach($tempArray as $x => $innerArray) {
if($i - $x >= 0 && $i - $x < $dimension) {
$diagonal[] = $innerArray[$i - $x];
}
}
if($i % 2 == 1) {
krsort($diagonal);
}
$returnArray = array_merge($returnArray,$diagonal);
}
return $returnArray;
}
Usage:
<?php
$a = range(1,25);
var_dump(waveSort($a));
Output
array(25) {
[0]=>
int(1)
[1]=>
int(6)
[2]=>
int(2)
[3]=>
int(3)
[4]=>
int(7)
[5]=>
int(11)
[6]=>
int(16)
[7]=>
int(12)
[8]=>
int(8)
[9]=>
int(4)
[10]=>
int(5)
[11]=>
int(9)
[12]=>
int(13)
[13]=>
int(17)
[14]=>
int(21)
[15]=>
int(22)
[16]=>
int(18)
[17]=>
int(14)
[18]=>
int(10)
[19]=>
int(15)
[20]=>
int(19)
[21]=>
int(23)
[22]=>
int(24)
[23]=>
int(20)
[24]=>
int(25)
}