ninedoors Posted August 23, 2007 Share Posted August 23, 2007 I have a sports website and I want to calculate the length of a team's streak whether it be a win, loss, or a tie. So I retreive the array that has all of the teams outcomes and then reverse it. This where I ran into the problem because I not sure what will work to get my desired result. Here is what I tried: <?php $array = array("win", "win", "win", "tie", "win", "win", "tie", "loss", "tie", "win" ); $array1 = array_reverse($array); $i = 1; $outcome = $array1[0]; while ($outcome == $array1[$i]) { $i++; } if ($array1[0] > 1) { echo "$i $array1[0] s"; } else { echo "$i $array1[0]"; } ?> The array above is just the test array I am using to see if the code is working but it's not. What I want is $streak = 3 wins, for this example array. any help would be great. Thanks Nick Quote Link to comment Share on other sites More sharing options...
Psycho Posted August 24, 2007 Share Posted August 24, 2007 I don't know why you would need to reverse it. A steak is the same whether it is goign forwards or backwards. Try this: <?php $winStreak = 0; $lossStreak = 0; $tieStreak = 0; $tmpWin = 0; $tmpLoss = 0; $tmpTie = 0; $outcomes = array("win", "win", "win", "tie", "win", "win", "tie", "loss", "tie", "win" ); foreach ($outcomes as $outcome) { switch ($outcome) { case 'win': $tmpWin++; $tmpLoss = 0; $tmpTie = 0; $winStreak = ($tmpWin>$winStreak)?$tmpWin:$winStreak; break; case 'loss': $tmpWin = 0; $tmpLoss++; $tmpTie = 0; $lossStreak = ($tmpLoss>$lossStreak)?$tmpLoss:$lossStreak; break; case 'tie': $tmpWin = 0; $tmpLoss = 0; $tmpTie++; $tieStreak = ($tmpTie>$tieStreak)?$tmpTie:$tieStreak; break; } ?> I'm sure there may be a more efficient solution, but this was the first to come to mind Quote Link to comment Share on other sites More sharing options...
Fadion Posted August 24, 2007 Share Posted August 24, 2007 Its kinda the same approach as mjdamato's: <?php $outcomes = array("win", "win", "win", "tie", "win", "win", "tie", "loss", "tie", "win" ); $maxStreak = 0; $streak = 0; foreach($outcomes as $value){ if($value == 'win'){ $streak++; if($streak > $maxStreak){ $maxStreak = $streak; } } else{ $streak = 0; } } echo $maxStreak; ?> Quote Link to comment Share on other sites More sharing options...
Psycho Posted August 24, 2007 Share Posted August 24, 2007 Here, this is a little more compact - I love efficiency <?php $outcomes = array("win", "win", "win", "tie", "win", "win", "loss", "loss", "tie", "win" ); $outcome_types = array ('win', 'loss', 'tie'); foreach ($outcomes as $outcome) { foreach ($outcome_types as $type) { $tmp[$type] = ($outcome==$type)? $tmp[$type]+1 : 0 ; $streaks[$type] = ($tmp[$type]>$streaks[$type])? $tmp[$type] : $streaks[$type] ; } } //Output the results foreach ($outcome_types as $type) { echo "The $type streak is: $streaks[$type]<br>"; } // Output: // The win streak is: 3 // The loss streak is: 2 // The tie streak is: 1 ?> Quote Link to comment Share on other sites More sharing options...
ninedoors Posted August 24, 2007 Author Share Posted August 24, 2007 GuiltyGear, Your code works but it only finds the 'win' streaks. I need to find any streak. Meaning a streak of ties, losses or wins. Nick Quote Link to comment Share on other sites More sharing options...
hitman6003 Posted August 24, 2007 Share Posted August 24, 2007 This will be faster with a larger number of items in the $outcomes array: for ($i = 0; $i < count($outcomes); $i++) { if (!$streaks[$outcomes[$i]]) { $streaks[$outcomes[$i]] = 1; $current_streak = 1; } if ($outcomes[$i] == $outcomes[$i + 1]) { $current_streak++; if ($current_streak > $streaks[$outcomes[$i]]) { $streaks[$outcomes[$i]]++; } } else if ($outcomes[$i] != $outcomes[$i + 1]) { $current_streak = 1; } } With 10 entries, they are about the same, with 100 entries the above is about 2.5 times faster. <?php $possible = array('win', 'tie', 'loss'); while (count($outcomes) <= 100) { $outcomes[] = $possible[array_rand($possible)]; } $start = microtime(); for ($i = 0; $i < count($outcomes); $i++) { if (!$streaks[$outcomes[$i]]) { $streaks[$outcomes[$i]] = 1; $current_streak = 1; } if ($outcomes[$i] == $outcomes[$i + 1]) { $current_streak++; if ($current_streak > $streaks[$outcomes[$i]]) { $streaks[$outcomes[$i]]++; } } else if ($outcomes[$i] != $outcomes[$i + 1]) { $current_streak = 1; } } echo 'completion time for method: ' . (microtime() - $start) . ' seconds<br />Result:'; echo '<pre>' . print_r($streaks, true) . '</pre>'; $start = microtime(); $outcome_types = array ('win', 'loss', 'tie'); foreach ($outcomes as $outcome) { foreach ($outcome_types as $type) { $tmp[$type] = ($outcome==$type)? $tmp[$type]+1 : 0 ; $streaks[$type] = ($tmp[$type]>$streaks[$type])? $tmp[$type] : $streaks[$type] ; } } echo 'completion time for method: ' . (microtime() - $start) . ' seconds<br />Result:<br />'; foreach ($outcome_types as $type) { echo "The $type streak is: $streaks[$type]<br>"; } //echo '<pre>' . print_r($outcomes, true); ?> increasing the number of entries keeps the ratio about the same. EDIT: I did test with a larger number of possibilities...6 to be exact: win, loss, tie, one, two, three. This makes the time difference even larger: almost 5 times faster. Although I don't know why you would have six possible results..... Quote Link to comment Share on other sites More sharing options...
ninedoors Posted August 24, 2007 Author Share Posted August 24, 2007 I fixed it GuiltyGear. Thanks, that works great. Here's what I did incase you were wondering. <?php $outcomes = array("win", "win", "win", "tie", "loss", "tie", "win" ); $maxStreak = 0; $streak = 0; $a = $outcomes[0]; foreach($outcomes as $value){ if($value == $a){ $streak++; if($streak > $maxStreak){ $maxStreak = $streak; } } else{ $streak = 0; } } echo $maxStreak; ?> Quote Link to comment Share on other sites More sharing options...
Psycho Posted August 24, 2007 Share Posted August 24, 2007 Ok, I conceded that your process is faster than my 2nd attempt. But, I guess I should have been clearer on what "efficiency" I was after - which was efficiency in code, not necessarily speed. Were only talking about thousands of a second difference. And, since you brought it up, my original code was about 2 - 3 times faster than the code you posted. Quote Link to comment Share on other sites More sharing options...
Psycho Posted August 24, 2007 Share Posted August 24, 2007 I fixed it GuiltyGear. Thanks, that works great. Here's what I did incase you were wondering. <?php $outcomes = array("win", "win", "win", "tie", "loss", "tie", "win" ); $maxStreak = 0; $streak = 0; $a = $outcomes[0]; foreach($outcomes as $value){ if($value == $a){ $streak++; if($streak > $maxStreak){ $maxStreak = $streak; } } else{ $streak = 0; } } echo $maxStreak; ?> Do you realize that will only find the longest streak for the first outcome type in the array, not necessarily the longest streak? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.