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 Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/ 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 Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332455 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; ?> Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332462 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 ?> Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332472 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 Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332515 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..... Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332517 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; ?> Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332543 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. Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332602 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? Link to comment https://forums.phpfreaks.com/topic/66418-solved-calculating-length-of-a-streak/#findComment-332606 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.