How can i make the for loop parameters dynamic - php

for ($i=40; $i>=30; $i--) //code will display data for top x row
for ($i=1; $i<=9; $i++) //code will display data for left y column
for ($i=29; $i>=21; $i--) //code will display data for bottom x row
for ($i=30; $i>=39; $i++) //code will display data for right y column
These 4 loops all do the same thing.
In my index.php im using "include" to get the 4 loops that are in 4 different files.
How can I make the for loop dynamic?
Algoritihm:
$i = (40,1,29,30) <--will be any of those 4
$maxlow = (30,9,21,39)
$check =(>,<) <--value depends on whether $i > or < $maxlow
$icrement = (--,++) <-- if $check is > then decrease, otherwise increment
for ($i; $i($check)=$maxlow; $i($increment) <---what i am trying to do

// $step is either 1 (incrementing) or -1 (decrementing)
foreach (range($begin, $maxlow, $step) as $i) {
}

Settings for given loop:
$diff = -1;
$start = 40;
$stop = 30 + $diff;
The loop itself, always like this:
for ($i = $start; $i != $stop; $i += $diff)

$low = [40,1,29,30](rand(0,3);
$high = [30,9,21,39](rand(0,3);
$modifier = ($low > $high) ? -1 : 1;
for($i = $low; ($i * $modifier) < ($high * $modifier); $i += $modifier)
{
doStuff();
}

why not just use for with switch inside, like this:
for ($i=1; $i >=39; $i++) {
switch($i) {
case ($i>=1 && $i<=9):
break;
...
...
case ($i>40):
//do something
break;
}
}
It will be much more readable, and easier to understand/edit in future.

Related

For loop (php) that results in this: 12345678910987654321

My niece is trying to create one for-loop (php), that results in this:
* 12345678910987654321
example for loop she tried:
for ($i = 1; $i <= 10; $i++ , $i = 10; $i <= 1; $i--) {
echo $i . ' ';
}
She can only use if's and elseif's. I'm not a programmer and can't really help her. Any ideas how this could be achieved in php?
Any information would be greatly appreciated.
The key is to add a variable instead of a number, then reverse that number when $i hits 10.
for($i = 1, $j = 1; $i> 0; $i+=$j) // Start i at 1, and j at 1
{
echo $i;
if($i == 10)
$j = -1; // i has hit 10, so use -1 to start subtracting
}
Another possibility is to loop up to 20, printing $i for the ascending part and 20 - $i for the descending.
for ($i = 1; $i < 20; $i++) {
if ($i <= 10) {
echo $i;
} else {
echo 20 - $i;
}
}

PHP Get Experience by Level

I have this piece of code that loops 1 through 99 and is a formula.
function getExperienceByLevel ($maxLevel)
{
$levels = array ();
$current = 0;
for ($i = 1; $i <= $maxLevel; $i++)
{
$levels[$i - 1] = floor ($current / 4);
$current += floor($i+300*pow(2, ($i/9.75)));
}
return $levels;
}
First you initiate it like so $aLevels = getExperienceByLevel(99); then to see how much EXP you need to get to level 6 you do this echo $aLevels[5]; since it's an array.
Now I'm trying to do reverse. Get Level by EXP.
function getLevelByExp($exp)
{
$myLevel = 0;
$aLevels = getExperienceByLevel(99);
for ($i = 1; $i < 100; $i++)
{
if ($exp > $aLevels[$i-1])
{
return $myLevel;
}
}
}
When called upon getLevelByExp(1124); or any number inside, it seems to return a zero. But it seems to work when you put echos inside that statement.
Like instead of return $myLevel do echo "You are up to level $i<br />"; and it will go all the way up to the current level you've gained EXP for.
But still.. doesn't work when I want to simply return a number.
This seems to work better than your function:
function getLevelByExp($exp)
{
$aLevels = getExperienceByLevel(99);
for ($i = 0; $i <= 99; ++$i)
{
//echo "cmp $exp >= aLevels[$i]={$aLevels[$i]}\n";
if ($exp <= $aLevels[$i])
return $i - 1;
}
return -1;
}
It needs improvement for the edge cases, such as when $exp is zero.
Return $i instead because it always '0'
if ($exp > $aLevels[$i-1]) {
return $i;
}
You never change $myLevel, so it will always stay at 0.
Try returning $i instead of $myLevel, as $i is actually changing:
function getLevelByExp($exp) {
$aLevels = getExperienceByLevel(99);
for ($i = 1; $i < 100; $i++) {
if ($exp > $aLevels[$i-1]) {
return $i;
}
}
}

Get number by loop on if - PHP

I have this piece of code that loops 1 through 99 and is a formula.
function getExperienceByLevel ($maxLevel)
{
$levels = array ();
$current = 0;
for ($i = 1; $i <= $maxLevel; $i++)
{
$levels[$i - 1] = floor ($current / 4);
$current += floor($i+300*pow(2, ($i/9.75)));
}
return $levels;
}
First you initiate it like so $aLevels = getExperienceByLevel(99); then to see how much EXP you need to get to level 6 you do this echo $aLevels[5]; since it's an array.
Now I'm trying to do reverse. Get Level by EXP.
function getLevelByExp($exp)
{
$aLevels = getExperienceByLevel(99);
for ($i = 1; $i < 100; $i++)
{
if ($exp > $aLevels[$i-1])
{
return $i;
}
}
}
So I try to do this:
$aLevels = getExperienceByLevel(99);
echo getLevelByExp(131);
When called upon getLevelByExp(131); or any number inside, it seems to return a 1 even though it should be 2 since Level 3 is 167 EXP and Level 2 is 80 EXP. Here's a reference image: http://i.imgur.com/gEYgu.png
function getLevelByExp($exp) {
$aLevels = getExperienceByLevel(99);
for ($i = 99; $i >= 1; $i--)
{
if ($exp > $aLevels[$i-1])
{
return $i;
}
}
}
You are returning as soon as $exp > $aLevels[$i-1]. On the first runthrough of your original loop, $aLevels[$i-1] = $aLevels[0] = 0, so it will always return right away for any non-negative $exp value.
You are doing two mistakes: You are indexing your levels array wrong. And you're checking it the wrong way. Use this:
http://codepad.viper-7.com/MGpOUu
function getExperienceByLevel($maxLevel) {
$levels = array ();
$current = 0;
for ($i = 1; $i <= $maxLevel; $i++) {
$levels[$i] = floor ($current / 4);
$current += floor($i+300*pow(2, ($i/9.75)));
}
return $levels;
}
function getLevelByExp($exp) {
$levels = getExperienceByLevel(99);
$current = 0;
foreach($levels as $level => $required) {
if($required>$exp)return $current;
$current = $level;
}
return $current;
}
echo getLevelByExp(131);
// returns 2
change
if ($exp > $aLevels[$i-1])
to
if ($exp > $aLevels[$i-1] && $exp < $aLevels[$i])
checked and it is working
working example http://codepad.viper-7.com/BjmHad
You need the opposite conditional, and to compare to the next level, so you can determine that a given exp level does not fit into any higher level. This code works for me:
if ($exp < $aLevels[$i])
{
return $i;
}
Nice and simple. Try it out: http://codepad.viper-7.com/FrjtHT
I think you should do it like
function getLevelByExp($exp)
{
$aLevels = getExperienceByLevel(99);
for ($i = 1; $i < count($aLevels); $i++)
{
if ($exp >= $aLevels[$i-1] && ($exp - $aLevels[$i-1] < $aLevels[$i] - $aLevels[$i-1]))
{
return $i;
}
}
}
Check out http://www.phpfiddle.org/main/code/paw-08f

add in loop in multi dimensional array

i am facing a problem
can some one suggest me
for ($i = 1; $i <= 2; $i++) {
$r2 = 0;
for ($t = 1; $t <= 2; $t++) {
echo $r2;
$r2++
}
}
output is 0101;
can i get output 0123 ??? please
if
for ($i = 1; $i <= 3; $i++) {
$r2 = 0;
for ($t = 1; $t <= 3; $t++) {
echo $r2;
$r2++
}
}
output is 010101;
can output 012345678 ??? please
and if
for ($i = 1; $i <= 4; $i++) {
$r2 = 0;
for ($t = 1; $t <= 4; $t++) {
echo $r2;
$r2++
}
}
output is 01010101;
can output 0123456789101112131415 ??? please
i think you understand
thanks
In all of these cases you are initializing $r2=0; in the inner loop. It should be outside the loop.
$r2=0;
for($i=1;$i<=2;$i++){
for($t=1;$t<=2;$t++){
echo $r2;
$r2++
}
}
This would produce "1234".
why are you using two nested for loops ?
why not just use one:
for ($i=0; $i<=15; $i++) echo $i . " ";
Try this:
$r2 = 10;
for($t = 0; $t <= $r2; $t++){
echo $r2;
}
Oh wait.. I get it now, why you have the two nested loops, you want to essentially raise a number to the power of 2 in order to control the number of values output. In that case, what you want is simply this:
// this is the variable you need to change to affect the number of values outputed
$n = 2;
// Square $n
$m = $n * $n;
// Loop $m times
for ($i = 0; $i < $m; $i++) {
echo $i;
}

Loop Code Optimization

How can I optimize the following code ,
I Need to run 3 sets of loops like this:
for($i=1;$i<=$count-1;$i++){
for($j=$i+1;$j<=$count;$j++){
// do some query use $i and $j
}
}
for($i=1;$i<=$count-2;$i++){
for($j=$i+1;$j<=$count-1;$j++){
for($k=$j+1;$k<=$count;$k++){
// do some query use $i and $j and $k
}
}
}
for($i=1;$i<=$count-3;$i++){
for($j=$i+1;$j<=$count-2;$j++){
for($k=$j+1;$k<=$count-1;$k++){
for($l=$k+1;$l<=$count;$l++){
// do some query use $i and $j and $k and $l
}
}
}
}
Is there a way to simplify the code, perhaps to connect the loops together ?
thanks !
This should do it (untested):
for($i = 1; $i <= $count - 3; $i++) {
for($j = $i + 1; $j <= $count; $j++) {
// i,j query
if($j > $count - 2) {
continue;
}
for($k = $j + 1; $k <= $count; $k++) {
// i,j,k query
if($k > $count - 1) {
continue;
}
for($l = $k + 1; $l <= $count; $l++) {
// i,j,k,l query
}
}
}
}
Note that the queries are no longer in their original order.
As it has been said, there's no way to optimize this further without knowing the queries you are running.
The big problem is that the inner loops are run multiple times. You can get around this by checking i === 1 and j === 2 inside the loops and only running the appropriate code if true.
Micro-optimization:
Use
++$i
rather than
$i++
and equivalent for $j++, $k++ and $l++
But what are you doing in these loops: it's entirely possible that your do some query (database?) could be changed to remove the loops completely... and that would be far more effective than any micro-optimisations

Categories