foreach() every 4 change output - php

I have an issue where I don't know for a foreach() loop to change the output on every(x) amount of results.
Here is my foreach() code:
$dir_handle = 'assets/icons/';
foreach(array_diff(scandir($dir_handle), array('.', '..')) as $file) {
$cut = substr($file, -4);
echo '<img id="preload_header" src="assets/icons/' . $file . '" /><br />';
}
How would I get it for that 1-4 have the same result, but then 5-8 have a different result, and then back to 1-4?

You want to do a count in your foreach loop
$count = 1;
foreach(array_diff(scandir($dir_handle), array('.', '..')) as $file) {
//Check if count is between 1 and 4
if($count >= 1 && $count <= 4) {
//Do something
} else { //Otherwise it must be between 5 and 8
//Do something else
//If we are at 8 go back to one otherwise just increase the count by 1
if($count == 8) {
$count = 1;
} else {
$count++;
}
}
}

You can use the % operator, combined with a division by 4:
foreach ($a as $key => $val) {
$phase = $key / 4 % 2;
if ($phase === 0) {
echo 'here';
}
elseif ($phase === 1) {
echo 'there';
}
}
This switches between the two branches every 4 iterations of your loop.
As pointed out in the comments, the above method assumes that the keys of your array are in order. If not, you can add a counter variable in the loop, like:
$c = 0;
foreach ($a as $val) {
$phase = $c++ / 4 % 2;
if ($phase === 0) {
echo 'here';
}
elseif ($phase === 1) {
echo 'there';
}
}

Related

I want to make an arrow that the base width is half of the size of the input

I have this code that works but is missing some details
$input=7;
$k=($input+1)/2;
for($i=1;$i<=$input;$i++){
for($j=1;$j<=$input;$j++){
if($j==($input+1)/2 || $j==$k || $j==$input-$k+1){
echo "*";
}
else{
echo "-";
}
}
echo "<br>";
$k++;
}
And the output look like this
---*---
--***--
-*-*-*-
*--*--*
---*---
---*---
---*---
My desired output is
___*___
__***__
_*****_
*******
__***__
__***__
__***__
In your if statement you have three conditions. So there can only be three stars in a row.
I think your structure is more complex as it should be. You could use str_repeat instead. Something like this:
$input=7;
for($i=1;$i<=$input;$i+=2) {
echo str_repeat('-', ($input - $i) / 2 ) .
str_repeat('*', $i) .
str_repeat('-', ($input - $i) / 2 ) .
'<br>';
}
$shaft = floor($input / 2);
for($i=1;$i<$input/2;$i++) {
echo str_repeat('-', ($input - $shaft) / 2 ) .
str_repeat('*', $shaft) .
str_repeat('-', ($input - $shaft) / 2 ) .
'<br>';
}
The first loop draws the triangle which is growing by 2 each row.
The second loop draws the shaft.
So if you need to do it only using loops and if else, you have to elaborate your if statement. Here's my solution:
$input = 7;
for($i=1;$i<=2*$input;$i+=2) {
for($k=1;$k<=$input;$k++) {
if(($i <= $input && $k > floor(($input - $i)/2) && $k <= ceil(($input + $i)/2)) ||
($i > $input && $k > ceil($input/4) && $k <= floor(3/4*$input))) {
echo "*";
} else {
echo "-";
}
}
echo "<br>";
}
Note: In the first loop I use $i+=2, so with every iteration $i increases by two. To get the right number of lines the loop continues till 2*$input.
The if statement has two parts. In the first part the triangle is drawn (adding two stars every row since $i increases by 2). In the second part, when $i becomes greater than $input, drawing the shaft, which is half the width and 1/4 of the width on each side.
I got the answer guys, thank you all.
$x=($input/2); $y=$x+1; $w=($input/2);
if($w%2==0) {
$w++;
}
for($i=1; $i<=$input; $i++) {
for($j=1; $j<=$input; $j++) {
if($j>=$x && $j<=$y) {
echo "*";
}
else {
echo "_";
}
}
if($i>(($input-1)/2)) {
$x=(($input-$w)/2)+1;
$y=($x+$w)-1;
}
else {
$x--;
$y++;
}
echo "<br>";
}

Loops mixed alphabet and number to have 3 characters string

I would like to loop alphabet and number in sequence to have 3 characters string until the result is true.
The sequence should be A00, A01....A99, B00, B01....Z99 then AA1, AA2...and the last is ZZ9
I tried using this; it's able to generate A01 to Z99
$success = false;
foreach (range('A', 'Z') as $x)
{
if ($success === false)
{
for ($y = 0;$y < 100;$y++)
{
if ($success === false)
{
$serialNo = $x . sprintf("%02d", $y);
}
else
{
break;
}
}
}
}
Using this, I managed to get AA9 to ZZ9
$success = false;
foreach (range('A', 'Z') as $x)
{
if ($success === false)
{
foreach (range('A', 'Z') as $y)
{
for ($z = 0;$z < 10;$z++)
{
if ($success === false)
{
$serialNo = $x . $y . $z;
}
else
{
break;
}
}
}
}
else
{
break;
}
}
If I just want to start the looping from a certain position, for example start from A99 or BB1, how can I do this? This is because I need to send the serialNo to a shared API which I don't know the last increment.
Example start from BB1.
foreach (range('B', 'Z') as $x)
foreach (range('B', 'Z') as $y)
for ($z = 1;$z < 10;$z++)
You simply to modify the start of the range to the character you are starting from.

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

php First value of array not displaying

I have the following bit of code and for some reason in the first WHILE loop the first value of $actor_list (when $i = 0) does not display. If I simply echo $actor_list[0] then it displays fine, but in the loop it will not display. I merely get [td][/td] as the output. The remaining values of the array display fine.
Also the line
echo '</tr><tr> </br>';
is not displaying.
What am I missing here? The value of $num_actors is an even number in my test scenario so there doesn't seem to be a reason for the above echo line to be skipped.
$actor_list = explode(" ", $actors);
$num_actors = count($actor_list);
if ($num_actors <= 6) {
foreach ($actor_list as $actor) {
echo '[td]'.$actor.'[/td] </br>';
}
} elseif ($num_actors <= 12) {
if ($num_actors % 2 == 0) {
$half_actors = $num_actors / 2;
while ($i <= ($half_actors - 1)) {
echo '[td]'.$actor_list[$i].'[/td] </br>';
$i++;
}
echo '</tr><tr> </br>';
while ($i <= $num_actors) {
echo '[td]'.$actor_list[$i].'[/td] </br>';
$i++;
}
}
}
You're not initialising the variable $i to 0, which means it will be set to 'null' and thus not reference the 0th index of the array; but when it's then incremented its value will become 1.
Note: [..] Decrementing NULL values has no effect too, but incrementing them results in 1.
See: http://php.net/manual/en/language.operators.increment.php
Try adding:
$i = 0;
before the if statement.
Made a few changes.
This is working for me.
Try it out.
<?php
$actor_list = 'act1 act2 act3 act4 act5 act6';
$actors = explode(" ", $actor_list);
$num_actors = count($actor_list);
//debug
//echo "<pre>";
//print_r($actor_list);
//echo "</pre>";
echo "<table>";
if ($num_actors <= 6) {
foreach ($actors as $actor) {
echo '<tr><td>'.$actor.'</td></tr>';
}
} elseif ($num_actors <= 12) {
if ($num_actors % 2 == 0) {
$half_actors = $num_actors / 2;
while ($i <= ($half_actors - 1)) {
echo '<tr><td>'.$actor_list[$i].'</td></tr>';
$i++;
}
while ($i <= $num_actors) {
echo '<tr><td>'.$actor_list[$i].'</td></tr>';
$i++;
}
}
}
echo "</table>";
?>

Pseudo-code for shelf-stacking

Suppose I have some serially numbered items that are 1-n units wide, that need to be displayed in rows. Each row is m units wide. I need some pseudo-code that will output the rows, for me, so that the m-width limit is kept. This is not a knapsack problem, as the items must remain in serial number order - empty spaces at the end of rows are fine.
I've been chasing my tail over this, partly because I need it in both PHP and jQuery/javascript, hence the request for pseudo-code....
while (!items.isEmpty()) {
rowRemain = m;
rowContents = [];
while (!items.isEmpty() && rowRemain > items[0].width) {
i = items.shift();
rowRemain -= i.width
rowContents.push(i);
}
rows.push(rowContents);
}
Running time is Θ(number of items)
Modulus is your friend. I would do something like:
$items = array(/* Your list of stuff */);
$count = 0;
$maxUnitsPerRow = 4; // Your "m" above
while ($item = $items[$count]) {
if ($count % $maxUnitsPerRow == 0) {
$row = new row();
}
$row->addItemToRow($item);
$count++;
}
Here is an alternative php code ...
function arrayMaxWidthString($items, $maxWidth) {
$out = array();
if (empty($items)) {
return $out;
}
$row = $maxWidth;
$i = 0;
$item = array_shift($items);
$row -= strlen($item);
$out[0] = $item;
foreach ($items as $item) {
$l = strlen($item);
$tmp = ($l + 1);
if ($row >= $tmp) {
$row -= $tmp;
$out[$i] = (($row !== $maxWidth) ? $out[$i] . ' ' : '') . $item;
} elseif ($row === $maxWidth) {
$out[$i] = $item;
++$i;
} else {
++$i;
$row = $maxWidth - $l;
$out[$i] = $item;
}
}
return $out;
}
For what it's worth, I think I have what I was looking for, for PHP - but not sure if there is a simpler way...
<?php
// working with just a simple array of widths...
$items = array(1,1,1,2,1,1,2,1);
$row_width = 0;
$max_width = 2;
echo "Begin\n"; // begin first row
foreach($items as $item=>$item_width) {
// can we add item_width to row without going over?
$row_width += $item_width;
if($row_width < $max_width) {
echo "$item_width ";
} else if($row_width == $max_width) {
echo "$item_width";
echo "\nEnd\nBegin\n"; // end last row, begin new row
$row_width = 0;
} else if($row_width == 2* $max_width) {
echo "\nEnd\nBegin\n"; // end last row, begin new row
echo "$item_width";
echo "\nEnd\n"; // end new row
$row_width = 0;
if($item < count($items)) echo "Begin\n"; // new row
} else if($row_width > $max_width) {
echo "\nEnd\nBegin\n"; // end last row, begin new row
echo "$item_width";
$row_width = $item_width;
}
}
echo "\nEnd\n"; // end last row
?>

Categories