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);
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