Jump to content

[SOLVED] Calculating length of a streak


ninedoors

Recommended Posts

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

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

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;
?>

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

?>

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.....

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;
?>

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.

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?

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.