Problem
This is my naive approach:
$sample1 = [3, 20, 1, 19, 4, 6, 77, 1, 0, 6];
$sample3 = [4, 5, 7, 0, 2, 44, 3, 5, 66, 7];
$sample4 = [4, 25, 1, 6, 9, 5, 999, 4, 43, 2];
$sample2 = [];
for ($i = 0; $i < mt_rand(10, 30); $i++) {
$sample2[] = mt_rand(1000, 1000);
}
extractNumbersThatSquaresAreGreaterThan($sample1);
extractNumbersThatSquaresAreGreaterThan($sample2);
extractNumbersThatSquaresAreGreaterThan($sample3);
extractNumbersThatSquaresAreGreaterThan($sample4);
var_dump($sample1);
//var_dump($sample2);
var_dump($sample3);
var_dump($sample4);
function extractNumbersThatSquaresAreGreaterThan(&$list, $boundary = 26) {
foreach ($list as $key => $value) {
if (pow($value, 2) <= $boundary) {
unset($list[$key]);
}
}
}
Any hints for optimization? Is it possible, I’ve tried few, but in the end it was more complicated (and slower) solution
Solution
Hints? Ok.

Don’t square the values, O(n), instead squareroot the boundary. You’ll need an
or
in your test, though. 
Don’t
unset
values in the list. That requires shifting values in memory. Make a new list of same size, fill in values, without gaps, and then resize result.
I don’t know about how fast this solution will be, but anyway I suggest to use functional approach to solve your problem. At least you will have concise code:
$sample4 = [4, 25, 1, 6, 9, 5, 999, 4, 43, 2];
var_dump(extractNumbers($sample4, 26));
function extractNumbers($list, $boundary) {
return array_filter($list, function($x) use ($boundary) {
return ($x * $x) > $boundary;
});
}
Instead of remove items with unset
, I would use array_filter
. And in fact, you could factor out the pow
function, if you use basic maths.
combining this would result in
function extractNumbersThatSquaresAreGreaterThan(&$list, $boundary = 26) {
$sqrt_boundary = sqrt($boundary);
$list = array_filter($list, function ($item) use ($sqrt_boundary) {
return abs($item) > $sqrt_boundary;
});
}
In addition, I would avoid the use of referenes for this task and just return your value.
function extractNumbersThatSquaresAreGreaterThan($list, $boundary = 26) {
$sqrt_boundary = sqrt($boundary);
return array_filter($list, function ($item) use ($sqrt_boundary) {
return abs($item) > $sqrt_boundary;
});
}