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

Link to comment
Share on other sites

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
Share on other sites

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
Share on other sites

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
Share on other sites

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
Share on other sites

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
Share on other sites

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
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

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