PHP: byebye

20 01 2019

 

If you think that this blogpost represents my swansong to PHP, know that I’ve been enamored of it since 1999, albeit nowadays a little less heady and more open-minded about competing technologies. The salutation entitling this blog post refers to an academic exercise, reminiscent of the fun  phun offered by fizbuzz.  In this case, the challenge involves  deriving the casual form “byebye” from “goodbye”. The impetus for this topic comes from an online discussion with respect to the C Programming Language (“C”), which caused me to ponder the merits of applying PHP for this purpose. 

Consider the following script:

<?php
$x = [-5,10,-10,-2,23,-20];
$y = "goodbye";
$p = $y;
for ($i=0; $i < 6; $i++){
    $p[$i] = // code?
}
$p[6] = "\0";
printf("%s\n",$p); //should print out "byebye"

The crux of issue, determining how to figure out the missing code that enables the for-loop iterations to eventually produce “byebye”. You may take a couple of approaches to bring about the desired result.  One of them relies on knowing the most appropriate of the built-in functions to apply. The official answer for the C exercise mentions writing code, as follows:

*(p+i) = (char)(*(p+i)+x[i]);

What one may glean from the one liner hints at a PHP solution, which I hoped would be something like the following:

<?php
// unsatisfactory solution!
$p[$i] = chr($p[$i] + $x[$i]); 

This PHP one-liner produces half a dozen warnings and while it prints characters, none spell out “byebye”. $p[$i] in a math context, despite the warnings, evaluates to zero which when added to the offset of an array element in $x, is unable to yield the desired character. In order to take the byte value of the character to which $p[$i] refers and do any meaningful math, one could resort to using the handy built-in ord(), as follows

<?php
for ($i=0,$j=1,$max = 6; $i < $max; $i++,$j++){
    $p[$i] = chr( ord($p[$i]) + $x[$i]);
}

However, it makes more sense to unpack all the ordinal values at once rather than extracting them as a loop iterates. So I suggest the following solution instead :

<?php
$x = [-5,10,-10,-2,23,-20];
$y = "goodbye";
$p = $y;
$ordvals = unpack("C*",$p);
for ($i=0,$j=1,$max = 6; $i < $max; $i++,$j++){
    $p[$i] = chr( $ordvals[$j] + $x[$i]);
}
$p[$i] = "\0";
printf("%s\n",$p); // byebye 

See live code

You may wonder why the code bothers to append a null character to “byebye” considering that PHP strings don’t require a terminal character. Since the code transforms “goodbye”, a 7-letter string into one which contains the 6-letter sequence “byebye”, one must  replace the seventh character “e” to avoid it shining through.

There is another way to answer this question, one which works directly with the string characters, as follows:

<?php
    define("MAX",strlen("byebye"));

    const SENDOFF = "goodbye";
    const START = 4; // position of "b" in goodbye

    $temp  = SENDOFF;

    for ( $i = 0; $i < MAX; $i++ ){
        $pos = START + ( $i % 3);
        $temp[$i] = SENDOFF[$pos];
    }
    $temp{$i} = "\0";
    printf("%s\n",$temp); // byebye 

See live code.

The for-loop uses the modulo operator to access each of the three letters that make up “bye”, going through the steps twice, and at every juncture assigning the string value to an element of array $temp. Note: with a constant one must use array square brackets to retrieve a string’s character, but with a variable the curly braces are a viable alternative.

So, you can take your pick as to which approach appeals to you. In any event, using PHP instead of C has the advantage of being able to avoid dealing with pointers.

In the meantime, byebye!

This work is licensed under a Creative Commons License

.

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.




%d bloggers like this: