15
\$\begingroup\$

I've tried this question on two forums and have been told this is the best place for this type of question. I'm trying to print from 0 to 1000 then back to 0 again (and all numbers in-between), printing 1000 only once. Also, each number must be on a separate line using vanilla PHP.

My current code is 60 characters long. Is there a way to do the same thing but in less characters?

PHP, 60 bytes

echo implode("<p>",array_merge(range(0,999),range(1000,0)));

Try it online!

\$\endgroup\$
7
  • 3
    \$\begingroup\$ Welcome! This looks like a solid tips question, but I suggest taking a look at this list and see if there's any more helpful info you can give. Where did the challenge originally come from? \$\endgroup\$
    – xnor
    Mar 17 '21 at 11:29
  • \$\begingroup\$ hi, thanks!. i'm studying on a course and its just like a bit of fun set by the trainer. i cant link the challenge because its on a private git hub. \$\endgroup\$
    – dev
    Mar 17 '21 at 11:31
  • \$\begingroup\$ I think it would be good to link a runnable version of your code. Is this right? I don't know PHP so I'm not sure if I did it right with the <?php around the code and the <p> for newlines. You can edit the code and the press the link icon at the top, and the copy-paste option for "Code Golf submission" can be pasted into your question. \$\endgroup\$
    – xnor
    Mar 17 '21 at 11:36
  • \$\begingroup\$ Also, we have Tips for golfing in PHP which might give you some inspiration. I noticed one mentioning array_merge which your code uses. \$\endgroup\$
    – xnor
    Mar 17 '21 at 11:37
  • 1
    \$\begingroup\$ May the list end with a trailing <p>? \$\endgroup\$
    – Sisyphus
    Mar 17 '21 at 11:40
20
\$\begingroup\$

PHP, 38 bytes

for(;$i-=1|$x|=$i/1001;)echo~$i,"<p>";

Try it online!

A one-byte improvement by JoKing. The idea is that by decrementing $i instead of incrementing it, we can save on the minus in the 1|-$x construction by having $x become -1 instead of 1 as a signal. This is achieved by using $i/1001, which is 0 if $i>-1001 and -1 otherwise. This would break even if not for the fact we can now use ~$i instead of $i-1.

PHP, 39 bytes

for(;$i+=1|-$x|=$i>1e3;)echo$i-1,"<p>";

Try it online!

In collaboration with primo on the code.golf discord.

The idea is to have a signal variable $x that is zero until $i hits 1000 then is 1 afterwards. We use the bitwise construction 1|-$x which is a shorter version of $x ? -1 : 1 to select whether to go upwards or downwards.

\$\endgroup\$
0
4
\$\begingroup\$

PHP,  56  49 bytes

Saved 7 bytes thanks to @Sisyphus and @xnor

My PHP is rusty, but here is a first attempt.

for(;$n<2e3;)echo 1e3-abs(1e3-$n++),'<p>';echo 0;

Try it online!

47 bytes

A shorter version suggested by @Neil:

echo 0;for(;$n<2e3;)echo'<p>',min(++$n,2e3-$n);

Try it online!

43 bytes

If the output can end with an extra <p>:

for(;$n<2001;)echo 1e3-abs(1e3-$n++),'<p>';

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ i was trying turnery but couldn't get it to work. \$\endgroup\$
    – dev
    Mar 17 '21 at 11:43
  • 1
    \$\begingroup\$ echo takes multiple arguments, so you can remove the brackets and replace . with , \$\endgroup\$
    – Sisyphus
    Mar 17 '21 at 11:47
  • 1
    \$\begingroup\$ It looks like 1e3-abs($n-1e3) is a byte shorter than the ternary. And shifting indices probably shortens that too. \$\endgroup\$
    – xnor
    Mar 17 '21 at 11:49
  • 1
    \$\begingroup\$ for(;$i<2001;)echo 1e3-abs(1e3-$i++),'<p>'; (thx @xnor) \$\endgroup\$
    – Sisyphus
    Mar 17 '21 at 11:49
  • \$\begingroup\$ I think echo 0;for(;$n<2e3;)echo'<p>',min(++$n,2e3-$n); is shorter for the first option, but I couldn't seem to adapt it for the second option. \$\endgroup\$
    – Neil
    Mar 17 '21 at 13:24
3
\$\begingroup\$

PHP, 51 bytes

echo join("<p>",[...range(0,999),...range(1e3,0)]);

Try it online!

There's already shorter versions, but I just wanted to show the OP how the original code can be shortened with the old alias join and the spread operator that is now available in PHP

Depending on your rules, even shorter:

49 bytes with <?=

<?=join("<p>",[...range(0,999),...range(1e3,0)]);

or even 47 with a literal new line, if your output can be wrapped in <pre><code>

<?=join("
",[...range(0,999),...range(1e3,0)]);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.