0

I want to print a series of conditionally modified numbers using a loop.

The logic is that the odd occurrences are printed without modification, but the even occurrences are squared (multiplied by themselves).

for ($i=1; $i < 6 ; $i++) { 
    echo $i;
    for ($j=1; $j==$i ; $j++) { 
        echo ($j+1) * ($j+1);
    }
    echo " ";
}

The above code prints: 14 2 3 4 5.

My desired result (if iterating 1 through 6) is:

//    unmodified
//    ↓   ↓    ↓
      1 4 3 16 5 36
//      ↑   ↑↑   ↑↑
//      squared (2, 4, and 6)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136

3 Answers3

2

You need to start with 1 and add 2 each time through the loop. The even elements are the squares of the number after that number. So:

for ($i = 1; $i < 6; $i += 2) {
    echo $i . " " . (($i+1) * ($i+1)) . " ";
}

You don't need the inner loop.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • @Ajeet This answer has a slight vulnerability in that it can only properly process an even amount of numbers. Furthermore, you can pull out all of those parentheses by reducing the `for` loop incrementation and using a post-increment just after the echo: `for ($i = 1; $i < 6; ++$i) { echo $i++ , " " , $i * $i , " "; }` Demo: https://3v4l.org/gFVe4 – mickmackusa Jul 02 '18 at 00:44
  • @mickmackusa Not sure what you mean by the first point. There are always an even number of results because you're printing pairs of numbers. – Barmar Jul 02 '18 at 04:16
  • Yes, I am only mentioning in case OP is running script on odd number of iterations: `$i=1; $i < 6` ...your way will offer the "extra" even occurrence. – mickmackusa Jul 02 '18 at 04:18
  • Regarding your suggested simplification, nothing in the [documentation](http://php.net/manual/en/function.echo.php) of the `echo` statement says that the arguments are evaluated left-to-right. – Barmar Jul 02 '18 at 04:18
  • http://php.net/manual/en/language.operators.increment.php My earlier 3v4l link demonstrates the behavior. This is not an attack. I upvoted everyone and only intend to spell things out and compare the approaches for future researchers. – mickmackusa Jul 02 '18 at 04:19
  • 1
    I'm not taking it as an attack.I'm just pointing out that using the incremented variable twice in the same statement is not well defined. Just because it works now doesn't mean it's guaranteed to work in all implementations. – Barmar Jul 02 '18 at 04:26
  • Is there an implementation where this doesn't work? Any reason to believe a future version would change this fundamental behavior? – mickmackusa Jul 02 '18 at 04:29
  • 1
    Is there a reason to depend on undocumented features just to save a couple of characters? – Barmar Jul 02 '18 at 13:20
1

Another way to do it by using %

<?php
$result = [];
for ($i=1; $i < 6 ; $i++) { 
    if($i%2==0){
        $result[] = pow($i,2);
    }else{
        $result[] = $i;
    }
}
echo implode(' ', $result);
?>

Program Output

1 4 3 16 5

DEMO: https://eval.in/1027936

A l w a y s S u n n y
  • 36,497
  • 8
  • 60
  • 103
  • @Ajeet The advantage to this solution is that there is no trailing whitespace because an array is generated and then imploded. This answer will be slower than the others, but not noticeably so--unless you are doing crazy-big sequences. – mickmackusa Jul 02 '18 at 00:45
1
<?php

for($i=1; $i<=6; $i++)
    echo $i&1 ? $i : $i*$i , ' ';

Because you can determine the nth term, we could write a function to get the nth number:

function ajeet_number($n) {
    return $n&1 ? $n : $n*$n;
}

And use that in a loop:

for($i=1; $i<=6; $i++)
    echo ajeet_number($i) . ' ';

Or apply that function to a range of numbers:

$s = array_map('ajeet_number', range(1,6));
echo implode(' ', $s);

Each output of above is similar:

1 4 3 16 5 36 

Reference: Test if number is odd or even

Progrock
  • 7,373
  • 1
  • 19
  • 25
  • @Ajeet Technically speaking the `&1` bitwise "odd check" comparison operator is the fastest possible conditional check. Conditional techniques allow greater flexibility (in case you have an odd number of input numbers to process). – mickmackusa Jul 02 '18 at 00:45