Detecting a cycle in an array PHP - php

I'm running a simple script which puts an integer through the formula of the Collatz conjecture and adds the output of each step into an array.
I want to use a function to detect if there's a cycle in the array, using Floyd's algorithm. And though I feel like I'm not doing a bad job, I don't seem to get it right. At this moment I'm getting the error Trying to get property 'next' of non-object in C:\xampp\htdocs\educom\week3\functions.php on line 12
See my code below. Any feedback is greatly appreciated!
include("functions.php");
$n = $_POST['number'];
$step = 0;
$reeks1 = array();
$cycle = 0;
echo "Your entry is: ". $n ."<br><br>";
while($n!==1 && $cycle==0){
$cycle = detect_cycle(array($reeks1));
if($n % 2 == 0){
$n = $n / 2;
array_push($reeks1, "$n");
$step++;
echo $step .": ". $n ."<br>";
}else{
$n = ($n * 3) + 1;
array_push($reeks1, "$n");
$step++;
echo $step .": ". $n ."<br>";
}
}
functions.php:
function detect_cycle($node){
if ($node==NULL){
return FALSE;
}
$turtle = $node;
$rabbit = $node->next;
while($rabbit != NULL){
if($rabbit === $turtle){
return TRUE;
}elseif($rabbit->next == NULL){
return FALSE;
}else{
$turtle = $turtle->next;
$rabbit = $rabbit->next->next;
}
}
return FALSE;
}

Check this out. IMPORTANT I don't know is this according to your theory. but it won't give you errors if you use like this.
function detect_cycle($node){
if ($node==NULL){
return FALSE;
}
$turtle = $node;
$rabbit = $node[0];
while($rabbit != NULL){
if($rabbit === $turtle){
return TRUE;
}elseif($rabbit[0] == NULL){
return FALSE;
}else{
$turtle = $turtle[0]; // use the number of the element key starting from 0
$rabbit = $rabbit[0][1];
}
}
return FALSE;
}

Related

Recursive function to find the number of ways a number can be generated out of a set of numbers

I had a job interview test and the question I got was about making a function which would return the number of ways a number could be generated by using numbers from a certain set and any number in the set can be used N times.
It is like if I have the number 10 and I want to find out how many ways 10 can be generated using [2,3,5]
2+2+2+2+2 = 10
5+3+2 = 10
2+2+3+3 = 10
5+5 = 10
to solve it I made this function:
function getNumberOfWays($money, $coins) {
static $level = 0;
if (!$level) {
sort($coins);
}
if ($level && !$money) {
return 1;
} elseif (!$level && !$money) {
return 0;
}
if ($money === 1 && array_search(1, $coins) !== false) {
return 1;
} elseif ($money === 1 && array_search(1, $coins) === false) {
return 0;
}
$r = 0;
$tmpCoins = $coins;
foreach ($coins as $index => $coin) {
if (!$coin || $coin > $money) {
continue;
}
$tmpCoins[$index] = 0;
$tmpMoney = $money;
do {
$tmpMoney -= $coin;
if ($tmpMoney >= 0) {
$level++;
$r += getNumberOfWays($tmpMoney, $tmpCoins);
$level--;
} elseif (!$tmpMoney) {
$r++;
}
} while ($tmpMoney >= 0);
}
return $r;
}
This function works ok and returns the right value.
My question is if there is a better way for it.
Thanks

Choose a string based on random number

I am working on a bit of PHP and I've come upon a bit of issues.
I am using PHP to randomly choose a number from 1-360. I am trying to compare the answer to a list of value determined by range.
$NumberA = rand(0,180);
$NumberB = rand(0,180);
$NumberC = $NumberA + $NumberB;
if ($NumberC = range(0,21) {
$result = "Orange";
}
elseif ($NumberC = range(22,42) {
$result = "Red";
}
elseif ($NumberC = range(43,63) {
$result = "Blue";
}
//This goes on for a while ...
else {
$result = "Green";
}
echo = $result;
Anytime i do this, the result always assigns the value of "Orange" to $result .
Im sure im doing something wrong here, please help!
First of all, you used just one '=' to compare while it should have been '=='. Second range() generates an array and you cannot compare an integer to an array. Third why generating the range every single time when you can check that $NumberC lies between the minimum and the maximum numbers of the range?
Change your code to:
$NumberA = rand(0,180);
$NumberB = rand(0,180);
$NumberC = $NumberA + $NumberB;
if ($NumberC >= 0 && $NumberC <= 21) {
$result = "Orange";
} elseif ($NumberC >= 22 && $NumberC <= 42) {
$result = "Red";
} elseif ($NumberC >= 43 && $NumberC <= 63) {
$result = "Blue";
} else {
$result = "Green";
}
echo $result;
Shall work. Hope this helps.

how to check an array if each following value is greater than the last

i am trying to find a way to validate some numbers in a php array, checking if each value is its greater than the last value.
Here is an example:
$number['num1']=1;
$number['num2']=2;
$number['num3']=3;
$number['num4']=4;
if($number['num1'] > $number['num2'] || $number['num1'] > $number['num3'] ||
$number['num1'] > $number['num4']){
//Some error
}
i can manually check each but is there an easier way, any suggestions?
You can achieve this pretty easily with a simple loop and using the PHP array pointer functions next and current:
$array = [1,2,3,4];
$isValid = true;
$current = current($array);
while($next = next($array)) {
if($next <= $current) {
$isValid = false;
break;
}
$current = $next;
}
var_dump($isValid);
Example: http://ideone.com/3uHPMq
Scopey beat me to it, but here's what I did:
$number['nums'][4] = 4;
$number['nums'][2] = 2;
$number['nums'][1] = 600;
$number['nums'][3] = 3;
// Note, I rearranged the order above just to make sure it
// works no matter what order the values get put in
function isAscending($arr) {
ksort($arr);
for ($i=0; $i<count($arr); $i++) {
if (isset($arr[$i-1])) {
if ($arr[$i-1] > $arr[$i]) {
return false;
}
}
}
return true;
}
var_dump(isAscending($number['nums'])); // false

Is there anyway to repeat the biggest segment of continuous segment of repeat using php?

I want to put the input like "RKKRRRRK" and try to get the output like largest continuous segment.. Suppose my input may be "RKKKR" then my program will display 'KKK' is the largest continuous segment.. and then it also display the count is 3..
I've already write the code for counting 'R' values.. now i want this program also... need help anyone help me.. thanks in advance.
Here the code:-
<?php
function numberOfR($string1)
{
for($i=0;$i <strlen($string1);$i++)
{
if($string1[$i]!='K')
{
$count++;
}
}
return $count;
}
$return_value= numberOfR("RKKRK");
echo "R's count is:";
echo $return_value;
?>
<?php
function getLongetSegment($string) {
$currentSegmentChar='';
$currentSegment="";
$biggestSegment="";
$current_length=0;
$biggest_length=0;
for($i=0;$i<strlen($string);$i++) {
$char = $string[$i];
if($char != $currentSegmentChar || $currentSegmentChar == '') {
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
$biggest_length = $current_length;
}
$currentSegmentChar = $char;
$currentSegment = $char;
$current_length = 1;
}
elseif($currentSegmentChar != '') {
$currentSegment .= $char;
$current_length++;
}
}
if($current_length >= $biggest_length) {
$biggestSegment = $currentSegment;
}
return array("string" => $biggestSegment,"length" => $biggest_length);
}
print_r(getLongetSegment("RKKRGGG"));
?>
Result: GGG
You can use preg_match_all over here as
preg_match_all('/(.)\1+/i','RKKRRRRK',$res);
usort($res[0],function($a,$b){
return strlen($b) - strlen($a);
});
echo $res[0][0];
Not sure if I understood this quite right. Something like this:
function maxCharSequece($string1)
{
$maxSeq = $seq = 0;
$maxChar = $lastChar = null;
for( $i = 0; $i < strlen($string1); $i++ )
{
$c = $string1[$i];
if (!$lastChar) $lastChar = $c;
if ( $lastChar == $c ){
if ( ++$seq > $maxSeq ) $maxChar = $lastChar;
}
else {
$maxSeq = $seq;
$seq = 0;
}
}
return $maxChar;
}
You can use preg_replace_callback to receive all continuous segments and select the longest
$sq = '';
preg_replace_callback('/(.)\1+/',
function ($i) use (&$sq) {
if(strlen($i[0]) > strlen($sq)) $sq = $i[0];
}, $str);
echo $sq . " " . strlen($sq);

What is wrong with my code - circularly sorted array does not show any results

I had an interview today and the person asked me this question:
How do you find easily an item in a circularly sorted array
Since I didn't know the answer, I tried to find a solution. Here's what I have:
Thanks
<?php
function searchincircularsorterlist($a, $len, $num) {
$start=0;
$end=$len-1;
$mid = 0;
while($start<$end) {
$mid=$start+$end/2;
if ($num == $a[$mid]) {
return $num;
}
if($num<$a[$mid]) {
if($num<$a[$start] && $a[$start]<=$a[$start+1])
$start=$mid++;
else
$end=$mid--;
}
else {
if($num>$a[$end] && $a[$end-1]<=$a[end])
$end=$mid--;
else
$start=$mid++;
}
}
if ($start == $end && $num == $a[$start]) {
return $num;
}
return -1;
}
$array = array(7,8,9,0,1,2,3,4,5,6);
var_dump(searchincircularsorterlist($array,sizeof($array),4));
I am trying to work with a circularly sorted array but for some reason it does not work. What's wrong with my code?
1) learn priority of operations. You should have: $mid=($start+$end)/2; which you ended up dividing $end by 2 and then $start - the result. This is why you got an infinite loop.
2) use: $start=$mid+1; and not $start=$mid++; that will help reducing the number of loops
<?php
function searchincircularsorterlist($a, $len, $num) {
$start=0;
$end=$len-1;
$mid = 0;
while($start<$end) {
$mid=($start+$end)/2;
if ($num == $a[$mid]) {
return $num;
}
if($num<$a[$mid]) {
if($num<$a[$start] && $a[$start]<=$a[$start+1])
$start=$mid+1;
else
$end=$mid-1;
}
else {
if($num>$a[$end] && $a[$end-1]<=$a[end])
$end=$mid-1;
else
$start=$mid+1;
}
}
if ($start == $end && $num == $a[$start]) {
return $num;
}
return -1;
}
$array = array(7,8,9,0,1,2,3,4,5,6);
var_dump(searchincircularsorterlist($array,sizeof($array),4));

Categories