Search code examples
phpsubstringnested-loopsexplodestrlen

How to display specific letters from a list of words in a loop?


I received this challenge in an interview and I would like some help solving it.

Using the input string: PHP CODING TECH, produce the following output.

PCT
PHCT
PHPCT
PHPCOT
PHPCODT
PHPCODIT
PHPCODINT
PHPCODINGT
PHPCODINGTE
PHPCODINGTEC
PHPCODINGTECH

As I understand it, the logic is to explode the input string on the spaces and then in a loop structure, display the leading letter(s) of each word as a single string. During each iteration (after the first), the earliest incomplete word displays an additional leading letter.

This is my coding attempt:

$str = "PHP CODING TECH";
$a = explode(' ', $str);
for ($i=0; $i < count($a); $i++) {
    for ($j=0; $j < strlen($a[$i]) ; $j++) { 
        //echo "<pre>";
        $b[$i][$j] = explode(' ', $a[$i][$j]);
    }
}
echo "<pre>";
print_r($b);

Solution

  • Code: (Demo) (or with DO-WHILE())

    $input = "PHP CODING TECH";
    $counters = array_fill_keys(explode(' ', $input), 1); // ['PHP' => 1, 'CODING' => 1, 'TECH' => 1]
    
    $bump = false;                                        // permit outer loop to run
    while (!$bump) {                                      // while still letters to output....
        $bump = true;                                     // stop after this iteration unless more letters to output
        foreach ($counters as $word => &$len) {           // $len is mod-by-ref for incrementing
            echo substr($word, 0, $len);                  // echo letters using $len
            if ($bump && isset($word[$len])) {            // if no $len has been incremented during inner loop...
                ++$len;                                   // increment this word's $len
                $bump = false;                            // permit outer loop to run again
            }
        }
        echo "\n";                                        // separate outputs
    }
    

    Output:

    PCT
    PHCT
    PHPCT
    PHPCOT
    PHPCODT
    PHPCODIT
    PHPCODINT
    PHPCODINGT
    PHPCODINGTE
    PHPCODINGTEC
    PHPCODINGTECH
    

    Explanation:

    I am generating an array of words and initial lengths from the exploded input string. $bump is dual-purpose; it not only controls the outer loop, it also dictates the word which gets a length increase within the inner loop. $len is "modifiable by reference" so that any given word's $len value can be incremented and stored for use in the next iteration. isset() is used on $word[$len] to determine if the current word has more available letters to output in the next iteration; if not, the next word gets a chance (until all words are fully displayed).


    And while I was waiting for this page to be reopened, I whacked together an alternative method:

    $input = "PHP CODING TECH";
    $words = explode(' ', $input);                // generates: ['PHP', 'CODING', 'TECH']
    $master = '';                                 // initialize for first offset and then concatenation
    foreach ($words as $word) {
        $offsets[] = strlen($master);             // after loop, $offsets = [0, 3, 9]
        $master .= $word;                         // after loop, $master = 'PHPCODINGTECH'
    }
    $master_offsets = range(0, strlen($master));  // generates: [0,1,2,3,4,5,6,7,8,9,10,11,12]
    
    do {
        foreach ($offsets as $offset) {
            echo $master[$offset];
        }
        echo "\n";
    } while ($master_offsets !== ($offsets = array_intersect($master_offsets, array_merge($offsets, [current(array_diff($master_offsets, $offsets))]))));  // add first different offset from $master_offsets to $offsets until they are identical