function test_loop($x_values,$x, $y)
{
$x = $x + 1;
if($x < 10)
{
$x_values[] = $x."#"; // insert item 2#,3#,4# into array
}
//loop again if y is not = 3;
$y = $y + 1;
if($y < 5)
{
test_loop($x_values, $x, $y);
}
return $x_values;
}
function abc(){
$bababa = test_loop([],1,0);
foreach($bababa as $fpackage_id)
{
echo $fpackage_id;
}
}
abc();
Output :
2#
How to make the output become :
2#,3#,4#
if($y < 5)
{
test_loop($x_values, $x, $y);
}
You're not doing anything with the return value of the recursive function call.
You need to add the array returned from test_loop() to the existing array:
$x_values += test_loop($x_values, $x, $y);
Your code now prints: 2#3#4#5#6#
If you want the output to be 2#, 3#, 4#, 5#, 6#, you can use the implode() function instead of a loop:
echo implode (', ', $bababa);
You'll want to utilize pass by reference:
https://www.php.net/manual/en/language.references.pass.php
I haven't looked too closely at your code, you may need to make more changes than this... but this might work:
function test_loop(&$x_values,$x, $y)
{
$x = $x + 1;
if($x < 10)
{
$x_values[] = $x."#"; // insert item 2#,3#,4# into array
}
//loop again if y is not = 3;
$y = $y + 1;
if($y < 5)
{
test_loop($x_values, $x, $y);
}
return $x_values;
}
function abc(){
$bababa = test_loop([],1,0);
foreach($bababa as $fpackage_id)
{
echo $fpackage_id;
}
}
abc();
You should use array_push() function to add an element in the array
Documentation
if($x < 10)
{
array_push($x_values,$x.'#');
}
Related
function test_loop($x, $y)
{
static $x_values = array();
$x = $x + 1;
if($x < 10)
{
$x_values[] = $x."#"; // insert item 2#,3#,4# into array
}
//loop again if y is not = 3;
$y = $y + 1;
if($y < 5)
{
test_loop($x, $y);
}
echo "gula</br>";
return $x_values;
}
function abc(){
$bababa = test_loop(1,0);
foreach($bababa as $fpackage_id)
{
echo $fpackage_id;
}
}
abc();
Output :
gula
gula
gula
gula
gula
2#3#4#5#6#
The code call test_loop() function before echo "gula", so supposedly it should fail to echo "gula". How to make the Output become like below :
gula
2#3#4#5#6#
UPDATE :
I tried to move the echo and return into else{} statement as #Joel Hager suggested, end up no output on the return value.
function test_loop($x, $y)
{
static $x_values = array();
$x = $x + 1;
if($x < 10)
{
$x_values[] = $x."#"; // insert item 2#,3#,4# into array
}
//loop again if y is not = 3;
$y = $y + 1;
if($y < 5)
{
test_loop($x, $y);
}else{
echo "gula</br>";
return $x_values;
}
}
You should add a return statement on you recursive call to test_loop
if($y < 5)
{
return test_loop($x, $y);
}
This way the code execution goes back to test_loop.
function test_loop($x_values,$x, $y)
{
$x = $x + 1;
if($x < 4)
{
//I want to add $x value into $x_values variable, eg : $x_values = $x_values . $x;
//but $x_values = $x_values . $x; is not working, so I force to use $x_values = test_loop($x_values . $x . "##", $x, $y);
$x_values = test_loop($x_values . $x . "##", $x, $y);
}
//loop again if y is not = 3;
$y = $y + 1;
if($y < 3)
{
echo "kkk" . $y . "<br/>";
$x_values = test_loop($x_values . $x . "##", $x, $y);
}else{
echo "---------------------<br/>";
}
return $x_values;
}
function abc(){
$bababa = test_loop(0,1,0);
echo $bababa;
}
abc();
Output :
kkk1
kkk2
---------------------
kkk1
kkk2
---------------------
kkk1
kkk2
---------------------
kkk2
---------------------
02##3##4##5##3##4##2##3##4##3##
How to make the output become :
kkk1
kkk2
---------------------
02##3##
Why don't you try to make $x_values an array, and add values in $x_values as array items, $x_values[] = $x; and then when you're ready, just implode() those values into a string. Like this:
function test_loop($x_values,$x, $y)
{
$x = $x + 1;
if($x < 4)
{
$x_values[] = $x;
}
//loop again if y is not = 3;
$y = $y + 1;
if($y < 3)
{
echo "kkk" . $y . "<br/>";
$x_values[] = $x;
}else{
echo "---------------------<br/>";
}
return implode($x_values);
}
Just make sure that you also pass $x_values as an array initially:
function abc(){
$bababa = test_loop([0],1,0);
echo $bababa;
}
This is the code I have. It currently works as is, However I'm experimenting with loops and want to see it can be done with a while loop and how it would be done. With this code I can take 2 input numbers and display them, then point out all odds, add all evens, and add all the squares of the odds.
define ("B","<br/>");
$firstNum = $_POST["firstNum"];
$secondNum = $_POST["secondNum"];
if ($firstNum < $secondNum)
{
$firstNum = true;
}
elseif ($firstNum >= $secondNum)
{
$firstNum = "You didn't listen, dumb dumb!".'<br/>GO BACK';
}
echo "First Number: ".$firstNum."<br/>"."Second Number: ".$secondNum;
echo B;
echo B;
$numbers = array();
$numbers = range($firstNum, $secondNum);
$length = count($numbers);
$odds = array();
$sumSqOdds = 0;
$sumEven = 0;
$j = 0;
for ($x = 0; $x < $length; $x++)
{
if (($numbers[$x] % 2) == 1)
{
$odds[$j] = $numbers[$x];
$sumSqOdds = $sumSqOdds + pow ($numbers[$x], 2);
$j++;
}
else
{
$sumEven = $sumEven + $numbers[$x];
}
}
$x = 0;
$y = 0;
printf("The odd numbers between your integers are: ");
for ($x = 0; $x < $j; $x++)
{
echo $odds[$x];
echo ' ';
$y++;
if (($y % 10) == 0)
{
echo B;
}
}
echo B;
echo B;
printf("The sum of all even numbers between your integers is: ".$sumEven);
echo B;
echo B;
printf("The sum of the square of the odd numbers between your integers is: ".$sumSqOdds);
Here is my while loop but it seems to be infinite...
$numW = array ();
$numW = range ($firstNum, $secondNum);
$lengthW = count ($numW);
$oddsW = array ();
$sumSqOddsW = 0;
$sumEvenW = 0;
$j = 0;
$x = 0;
while ($x < $lengthW)
{
if (($numW[$x] % 2) == 1)
{
$oddsW[$j] = $numW[$x];
$sumSqOddsW = $sumSqOddsW + pow ($numW[$x], 2);
$x++;
$j++;
}
else
{
$sumEvenW = $sumEvenW + $numW[$x];
}
}
$x = 0;
$y = 0;
printf ("The odd numbers between your integers are: ");
while ($x < $j)
{
$x++;
echo $oddsW[$x];
echo "nbsp;";
$y++;
if (($y % 10) == 0)
{
echo B;
}
}
Equivalent loops:
for ($i = 0; $i < 10; $i++) {
echo $i;
}
$i = 0;
while ($i < 10) {
echo $i;
$i++;
}
For a loop to ever finish it has to change one of the two evaluating variables. So either $x, or $lengthW would have to change during iteration. You made an if statment, in the first case you define that X increases by 1, but in the else case you do not change any variable that then has an effect on either $x, or $lengthW
Nor is there any check that sees if the else state has been reached and to catch that by either changing $x or $lengthW in a later iteration.
As such there's an infinite loop as soon as you reach the else case.
The if statement uses the same $x value as the last iteration checking the same position of the $numW, as such nothing has changed since the last iteration and you'll hit the else again, and again, and so on.
while ($x < $lengthW)
{
if (($numW[$x] % 2) == 1)
{
$oddsW[$j] = $numW[$x];
$sumSqOddsW = $sumSqOddsW + pow ($numW[$x], 2);
$x++; //$x is increased by one, and as such, the loop will progress.
// remove this $x++ if you place it outside the if else statement.
$j++;
}
else // reached when ($numW[$x] %2) != 1
{
$sumEvenW = $sumEvenW + $numW[$x];
// No changes to $x or $lengthW as such you'll hit the else again
// this could be solved by either adding $x++; here.
}
// or by adding $x++; here
// (if you do add it here, remove it in the if case above,
// or you risk increasing it by 2 every iteration
}
I've already asked a similar question, but I need a different effect. The original question is here.
I have a simple array. The array length is always a square number. So 16, 25, 36 etc.
$array = array('1', '2', '3', '4' ... '25');
What I do, is arrange the array with HTML so that it looks like a block with even sides.
What I want to do, is sort the elements, so that when I pass the JSON encoded array to jQuery, it will iterate the array, fade in the current block, and so I'd get a circular animation. So I'd like to sort the array kind of like this
So my sorted array would look like
$sorted = array('1', '6', '11'', '16', '21', '22', '23' .. '13');
Is there way to do so?.. Thanks
Edit:
I'm trying to do this by creating matrix-like column/row arrays with this:
$side = 5;
$elems = $side*$side;
$array = range(1,$elems);
for($i=1; $i <= $side; $i++) {
for($x=$i; $x <= $elems; $x=$x+$side) {
$columns[$i][] = $x;
}
}
for($i=1, $y=1; $i <= $elems; $i=$i+$side, $y++) {
for($x=$i; $x < $side+$i; $x++) {
$rows[$y][] = $x;
}
}
My next step is to go down the first column, at the end if it go right on the last elements column, at the end up on the last element etc.. If anyone has a better idea that would be great :)
This will work as long as the grid is always square:
<?php
// The size of the grid - 5x5 in the example above
$gridSize = 5;
// Create a 2D array representing the grid
$elements = array_chunk(range(1, pow($gridSize, 2)), $gridSize);
// Find the half way point - this will be the end of the loop since we
// want to stop in the middle
$end = ceil($gridSize / 2);
// An array to hold the result
$result = array();
// The stopping point of the current interation
$stop = $gridSize;
// Loop from start to the middle
for ($i = 0; $i < $end; $i++) {
// start in the top left corner
$x = $y = $i;
// Traverse Y top to bottom
while ($y < $stop) {
$result[] = $elements[$y++][$x];
}
$y--;
$x++;
// Traverse X left to right
while ($x < $stop) {
$result[] = $elements[$y][$x++];
}
$x--;
$y--;
// Traverse Y bottom to top
while ($y >= $gridSize - $stop) {
$result[] = $elements[$y--][$x];
}
$y++;
$x--;
// Make sure we come in a level
$stop--;
// Traverse X right to left
while ($x >= $gridSize - $stop) {
$result[] = $elements[$y][$x--];
}
}
print_r($result);
See it working
This should work. You can pass any array to circularSort function and it will return your sorted array.
/*
Get the circular sorted array
*/
function circularSort($array)
{
//Get the length of array
$arrayLength = count($array);
//Find the square root of length of array
$arrayRows = sqrt($arrayLength);
//Divide the arrays in $arrayRows
$arrayChunks = array_chunk($array,$arrayRows);
$circularArray = array();
//Call Circular Array function .. Result will be stored in $circularArray
circularArray($arrayChunks,$circularArray);
return $circularArray;
}
/*
Loop arrayChunk in following order
1. Fetch first item from each chunks
2. Fetch all items from last chunk and remove that array from arrayChunk
3. Reverse elements in each remaining chunk
4. Reverse entire arrayChunk array
5. Repeat above 4 steps until $arrayChunks is empty
*/
function circularArray(&$arrayChunks, &$circularArray)
{
if(empty($arrayChunks))
{
return true;
}
//1. Fetch first item from each chunks
foreach($arrayChunks as &$arrayChunk)
{
$circularArray[] = array_shift($arrayChunk);
}
//Fetch Last Chunk from array
$lastChunk = array_pop($arrayChunks);
//2. Fetch all items from last chunk and remove that array from arrayChunk
foreach($lastChunk as $chunkElement)
{
$circularArray[] = $chunkElement;
}
//3. Reverse elements in each remaining chunk
foreach($arrayChunks as &$arrayChunk)
{
if (is_array($arrayChunk))
{
$arrayChunk = array_reverse($arrayChunk);
}
}
$arrayChunks = array_reverse($arrayChunks);
return circularArray(&$arrayChunks, &$circularArray);
}
e.g.
$array = range(1, 25);
$circularArray = circularSort($array);
Another approach in O(n):
<?php
function circ_sort ($inArray) {
$rowSize = pow(count($inArray), 0.5);
if((int)$rowSize != $rowSize) {
throw new InvalidArgumentException();
}
$rowSize = (int)$rowSize;
$round =-1;
for ($x =-1, $y=0, $count =0; $count < count($inArray);) {
if ($y > $x) {
if ($x +1 == $y) {
$direction = 'D'; //Down
$round ++;
$max_iter = $rowSize - (2 * $round);
} else {
$direction = 'L'; //Left
$max_iter = $y - $x -1;
}
} else if ($x > $y) {
$direction = 'R'; //Right
$max_iter = $rowSize - (2 * $round) -1;
} else if ($x == $y) {
$direction = 'U'; //Up
$max_iter = $rowSize - (2 * $round) -1;
}
switch ($direction) {
case 'D': //Down
for ($iter =0; $iter < $max_iter; $iter++) {
$x++;
$circArray[] = $inArray[$x*$rowSize + $y];
$count++;
}
break;
case 'R': //Right
for ($iter =0; $iter < $max_iter; $iter++) {
$y++;
$circArray[] = $inArray[$x*$rowSize + $y];
$count++;
}
break;
case 'U': //Up
for ($iter =0; $iter < $max_iter; $iter++) {
$x--;
$circArray[] = $inArray[$x*$rowSize + $y];
$count++;
}
break;
case 'L': //Left
for ($iter =0; $iter < $max_iter; $iter++) {
$y--;
$circArray[] = $inArray[$x*$rowSize + $y];
$count++;
}
break;
}
}
return ($circArray);
}
$array = range(1, 25);
$circ_array = circ_sort($array);
var_dump($circ_array);
?>
My solution:
The trick is: The first run is 5 then two runs of 4 elements, two of 3 elements, 2 of 2 elements and two of 1 element. (5,4,4,3,3,2,2,1,1) In each run it is incremented a state module 4. Depending on the state the runs goes in one direction or other.
Here is the code:
function circularSort(array $array) {
$n2=count($array);
$n=sqrt($n2);
if((int)$n != $n) throw new InvalidArgumentException();
$Result = Array();
$run =$n; $dir=1;
$x=0; $y=-1;
$i=0;
$st=0;
while ($run) {
while ($dir) {
for ($j=0; $j<$run; $j++) {
if ($st==0) $y++;
if ($st==1) $x++;
if ($st==2) $y--;
if ($st==3) $x--;
$p=$y * $n +$x;
array_push($Result,$array[$p]);
}
$st = ($st +1) & 3;
$dir--;
}
$dir=2;
$run--;
}
return $Result;
}
$a = range(1,25);
var_dump(circularSort($a));
I tried and tried and tried to get this code to work and kept coming up with zilch. So I decided to try it using "for loops" instead and it worked first try. Could somebody tell me why this code is no good?
<?php
$x = $y = 10;
while ($x < 100) {
while ($y < 100) {
$num = $x * $y;
$numstr = strval($num);
if ($numstr == strrev($numstr)) {
$pals[] = $numstr;
}
$y++;
}
$x++;
}
?>
you should reset y=10 inside the first while.
$x = 10;
while ($x < 100) {
$y = 10;
while ($y < 100) {
$num = $x * $y;
$numstr = strval($num);
if ($numstr == strrev($numstr)) {
$pals[] = $numstr;
}
$y++;
}
$x++;
}
You need to reset y before the y loop begins.
While($x < 100){
$y=10; //... rest of code
For loops which loop over an integer that is incremented I would prefer the for-loop:
for ($x=0; $x < 100; $x++) {
for ($y=10; $y<100; $y++) {
$num = $x * $y;
$numstr = strval($num);
if ($numstr == strrev($numstr)) {
$pals[] = $numstr;
}
}
}
IMHO this is much more readable and it's shorter, too.