1
\$\begingroup\$

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

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jun 26, 2018 at 12:00
\$\endgroup\$
2
  • \$\begingroup\$ Please fix the code \$\endgroup\$ Commented Jun 26, 2018 at 12:39
  • \$\begingroup\$ @YourCommonSense please provide me more test data, than I'll fix \$\endgroup\$ Commented Jun 26, 2018 at 13:13

3 Answers 3

2
\$\begingroup\$

Hints? Ok.

  1. Don’t square the values, O(n), instead square-root the boundary. You’ll need an or in your test, though.

  2. 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.

answered Jun 26, 2018 at 13:38
\$\endgroup\$
1
\$\begingroup\$

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;
 });
}
answered Jun 26, 2018 at 20:22
\$\endgroup\$
1
\$\begingroup\$

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.

$$ num^2 \leq boundary\\ \implies |num| \leq \sqrt{boundary} $$

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;
 });
}
answered Jun 29, 2018 at 10:00
\$\endgroup\$
1
  • \$\begingroup\$ Thanks a lot for this. Especially reminding me, that something like ABS exists ;) \$\endgroup\$ Commented Jun 30, 2018 at 19:18

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.