I need to write a function who prints Look-and-Say Sequence hat takes a number as nth iteration. The first iteration is 0 and output has to contain every previous lines. For example, if we test sequence(3), the result need to be :
1
11
21
1211
SO I made a function for each line and another to stack them but it doesn't work =/ Here's my code
<?php
function Conway($n)
{
if ($n == 1)
return "1";
if ($n == 2)
return "11";
for ($i = 3; $i <= $n; $i ) {
$str = "11";
$str = $str.'$';
$len = strlen($str);
$cnt = 1;
$tmp = "";
for ($j = 1; $j < $len; $j )
{
if ($str[$j] != $str[$j - 1])
{
$tmp = $tmp.$cnt 0;
$tmp = $tmp. $str[$j - 1];
$cnt = 1;
}
else $cnt ;
}
$str = $tmp;
}
return $str;
}
function sequence($nth) {
for ($i = 1; $i <= $nth 1; $i )
do {
echo Conway($i)."\n";
} while ($i > $nth 1);
}
CodePudding user response:
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.
CodePudding user response:
Is that you looking for ?
function sequence($str) {
$str .= '';
$len = strlen($str);
$count= 0;
$result= '';
$temp= $str[0];
for($i=0;$i<$len;$i ) {
if($temp!=$str[$i]) {
$result.=$count.$temp;
$temp = $str[$i];
$count=1;
} else {
$count ;
}
}
$result.=$count.$temp;
return $result;
}
$num = 1;
echo "$num\n";
for($i=0;$i<3;$i ) {
$num=sequence($num);
print $num."\n";
}
output 1 11 21 1211