Tips and Tricks for Code Golfing in PHP

I see there are ‘code golf tips’ topics for some languages, but not for PHP, so let me start one.
I list some generic, non-puzzle specific tips I encountered - this is intended for beginners, as I am not a PHP pro at all. The best submissions on leaderboard seem unimaginably compact for me, so I start this topic not for altruism, but in hope that some real pros share some more tips (but not spoilers) :slight_smile:

  • Use only <? instead of <?php and you can skip the ?> at the end. No space after <? is needed.
  • Use fgets(STDIN) instead of stream_get_line. Unfortunately, it also reads the CR (end-of-line) character, but that is not a problem with integers. For real strings, you can use rtrim(fgets(STDIN))
  • If you need multiple fgets (e.g. init and per turn input), use fgets($s=STDIN) … fgets($s) instead of using fgets(STDIN) twice.
  • No space needed in input parsing format string, e.g. fscanf(STDIN,"%d%d",$y,$x)
  • Use && || logical operators instead of ‘and or’. They have different precedence, so for example this expressions does not need any parentheses: if(a<$b||$c>0&&$d=1)
  • If possible, refactor comparison expressions to use < or > instead of <=, >=, ==, !=
  • Use the PHP v7.x spaceship operator $a<=>$b instead of ($a<$b?-1:($a>$b?1:0))
  • Use the Elvis operator $a?:$b if you find a case where you can (well, to be honest, so far I didn’t)
  • To iterate on characters of a string, use foreach(str_split($M)as$m) … $m … instead of for($i=0;$i<strlen($M);$i++) … $M[$i] …
  • Use while(1) instead of while(TRUE) for endless loops
  • Use echo $a."\n"; instead of echo ($a."\n"); echo is not a function but language construct. If you need to print single variable(s) and not an expression, then echo “$a\n”; also works.
  • Use join instead of implode. Unfortunately in PHP v7.x split is no longer possible instead of explode.
  • Use $a=$b=0; instead of $a=0;$b=0; Even better if you have an unrelated for cycle beforehand, you can reuse the init part to init an extra varible, e.g. for($i=$a=0;…
  • Use ternary operator instead of if…else
  • If you need to use same library function with a long name more than twice, then name it. E.g. use $f=‘strlen’; … $f(…) … $f(…) $f(…) instead of strlen(…) … strlen(…) … strlen(…)
  • This might be obvious, but single statement block don’t need { }
  • Use post-increment operators ++ within expression. Skip 3rd section of for loop. E.g. for($j=0;$j<7;) … $p[$j++ ] …
  • use $a=[] … instead of $a=array() …
  • Actually it is very rare when PHP really needs a whitespace. Only if a variable name would mix with a reserved word, e.g. foreach($P as$p) But foreach($P[$i]as$p) is fine.

EDIT: added:

  • you don’t need \n in the echo. A real linefeed in double qutes is fine in the source code and it is 1 byte less.
  • consider using fgetcsv for input parsing of multiple, space delimited variables. E.g. [$L,$M,$X,$Y]=fgetcsv(STDIN,0,’ ')
5 Likes
<?=`insert your bash code here`
1 Like

Okay, that’s nice and unbeatably efficient, but takes away the whole point of code golf on a given language as a fun exercise and learning the language a bit better… :slight_smile:

It is somewhat like writing a multiplayer bot that calls out to a much powerful machine on the cloud to perform the most resource intensive part of a search (i dont’ know whether it is possible or rest api calls are disabled to avoid such cheat.)

I’m not the one you have to convince. I already agree with you. But for CodinGame golf puzzles, you can’t beat a bash code most of the time. So if you want to win, this is the only choice.

If you want to have fun, you can use the others tricks.

Agree :slight_smile:
Then, this is an improvement suggestion for CG - show also a leaderboard that excludes the solutions using embedded bash or perl code.
E.g. my current solutions in PHP for the 4 puzzles (in abc order) are 302/224/136/136 characters. I am curious how far am I from what is achievable without bash but I have no way to tell.
There might be some additional language hacks which I don’t know (actually that is why I opened this topic), or there might be completely different algorithms / approaches I did not think of.

for(;;) - 1 byte less.

Also you can put some irrelevant instructions in the brackets:
fscanf(STDIN,"%s",...);for(;;){$x+=$y;$x%=10;}
vs
for(fscanf(STDIN,"%s",...);$x+=$y;$x%=10){}

1 Like

in 2023 you don’t need quotes anymore and you can combine a call with an assignment:
$f=strlen;$f();$f();
vs
($f=strlen)();$f();

1 Like

That’s true, but CG does not live in 2023 when it comes to PHP version. As of this writing, you need to use here the v7.3 syntax from 2018.

Agree. Though all of these tricks I tested in CG competitions. Works well on 7.3 so far.

1 Like

if($a<$b&&$c=$d)$e=$f;

instead of

if($a<$b){$c=$d;$e=$f;}

You win 1 byte
because ‘$c=$d’ is done only if ‘$a<$b’ is true

$m>>=1; $n>>=2; $p<<=8;

instead of

$m=floor($m/2); $n=floor($n/4); $p*=256;

You win 8 + 8 + 1 bytes
because you shift bits instead of multiply or divide

1 Like

Code golfing in PHP is about crafting concise and compact code to accomplish a specific task efficiently. Here are some tips and tricks for effective PHP code golfing:
Use Short Variable Names:

  • Opt for short variable names, especially in loops and one-liners.

// Instead of
$index = 0;
while ($index < 10) {
// code
$index++;
}

// Use
for ($i = 0; $i < 10; $i++) {
// code
}

You can even write that instead :

//If you need i = 0 to 9
for($i=-1;++$i<10;){
//code
}

//If you need i = 1 to 10
for($i=0;++$i<10;){
//code
}

//If you need to repeat code 10 times and i = 0 or null at the beginning.
for(;$i++<10;){
//code
}

//If you need to repeat code 10 times and i = 10 at the beginning
for(;$i–;){
//code
}

1 Like