As explained here en.wikipedia.org/wiki/Look-and-say_sequence, the idea is to construct a string based on the previous constructed string (in a loop):
To generate a member of the sequence from the previous member, read
off the digits of the previous member, counting the number of digits
in groups of the same digit. For example:
- 1 is read off as "one 1" or 11.
- 11 is read off as "two 1s" or 21.
- 21 is read off as "one 2, one 1" or 1211.
- 1211 is read off as "one 1, one 2, two 1s" or 111221.
- 111221 is read off as "three 1s, two 2s, one 1" or 312211.
An attempt to solve this problem, we'll have a function called lookAndSay($n) that accepts a number $n. Basically, that function will have a loop that runs $n times.
To simplify things, we'll have a another function, let's call it tokenize($str), that will basically count the occurrence of a number, concatenates that count to the number (like 31 where 3 is the number of occurrences of the number 1), repeat until all the numbers in the string $str are dealt with.
A usage of that function can result in (for example):
tokenize('11'); // returns: '21'
Our main function, lookAndSay($n), will call tokenize($str) after making some initialization and in the end will return the resulting string.
Here's a code sample illustrating what's being said:
/**
* A function that generate look-and-say sequence based on a number "$n"
*
* @param int $n
* @return string
*/
function lookAndSay(int $n): string {
if ($n <= 1) return '1';
/** "$lastSeq" will hold the latest sequence tokenized by "tokenize" function */
$r = $lastSeq = '1';
/** loop based on "$n" and construct the final string along the way */
while($n-- > 0) $r .= ' '.($lastSeq = tokenize($lastSeq));
/** return the look-and-say string for the number "$n" */
return $r;
}
/**
* A function that "tokenizes" a string of numbers
* and return a string having the format "CN" where C is the number of occurrences of a number N in the string
*
* @param string $str
* @return string
*/
function tokenize(string $str): string {
/** will hold the string of tokens that will be returned after the function finishes */
$r = '';
/** holds the count of a number in the string $str */
$c = 1;
for ($i = 0; $i < strlen($str); $i++) {
/** we still count the number of occurrences of the same number "$str[$i]" ... */
if($str[$i] == ($str[$i + 1] ?? '')) {
/** increment the count and skip the rest of the loop */
$c++;
continue;
}
/** at this point we have the count for "$str[$i]" number so we concatenate the result to the final string and reset the count to "1" to prepare it for the next number (if any) */
($r .= $c.$str[$i]) && ($c = 1);
}
/** return the "tokenized" string */
return $r;
}
A call to lookAndSay could result in:
echo lookAndSay(3); // prints: 1 11 21 1211
Also here's a live demo of the above attempt.