5

I'm trying to figure out how to write a tie-breaker function. The following records are all tied for one reason or another, so to break the tie, we sort each result and then go through each line. The tie is broken at the first point there is a difference.

In the example below on the first pass $result[c] is eliminated, but a and b are still tied. Then on the second pass a is eliminated because it is greater than b. So the result is b, a, c

$result[a] = array(1, 3, 4, 5);
$result[b] = array(1, 2, 3, 7);
$result[c] = array(2, 3, 3, 5);

And to make it even more complicated, I won't always have the same number of results to compare. It could be anything more than 2.

I really hope this makes sense.

1
  • I've added an answer that is 100% functional and produces the correct output. It will even work for an arbitrary number of competitors. Commented Jun 2, 2012 at 20:54

3 Answers 3

3

In php, you can actually compare arrays directly using relation operators

if ($result['a'] > $result['b']) {

}

php will just loop through the sub arrays, comparing their elements. There's more detail if you want to read http://php.net/manual/en/language.operators.comparison.php

Anyway, you can take advantage of this and just sort it.

asort($result);
print_r($result);

If you need a way to get the n'th place entry, do

asort($result);
print_r($result);
$ranked = array_keys($result);
$secondPlace = $ranked[1]; // a
print_r($result[$secondPlace]);

and if you need the rank indice of a letter

$letterRanks = array_flip($ranked);
echo $letterRanks['a']; // 1, for second 
Sign up to request clarification or add additional context in comments.

1 Comment

This nailed it. Once I have my results arrays sorted, which I had to do anyway the asort function did exactly what I needed with one line of code.
0
$i = 0;
while (count($result) > 1) {
   $winners = array();
   $best = PHP_INT_MAX;
   foreach ($result as $x) {
      if ($x[$i] == $best) {
         $winners[] = $x;
      } else if ($x[$i] < $best) {
         $winners = array($x);
         $best = $x[$i];
      }
   }
   $i++;
   $result = $winners;
}

This is just a quick and dirty piece of code... it doesn't handle the situation where the arrays are different sizes. Mostly because I'm not sure which of array(1,2,3) or array(1,2) should "win". Also, it doesn't do any array bounds checking or handle the situation where more than one array is tied after all elements have been compared.

1 Comment

Thanks for the answer Bob. Luckily the arrays will always be the same size. But your example resets the $result array after every iteration, surely that won't work? Oh, and if they're still tied after that process it falls to another process so we'd just need to know if it failed to resolve the ties.
0

Here is a working solution. Let me know if you need a better explanation of how it works. I've left the debugging statements in so you should be able to discern what it is doing. This solution will work with an arbitrary number of competitors, as long as they each have the same $num_elements in each array.

$result = array();
$result['a'] = array(1, 3, 4, 5);
$result['b'] = array(1, 2, 3, 7);
$result['c'] = array(2, 3, 3, 5);

$num_elements = 4; // In each array
$num_competitors = count( $result);

$finish_order = array();
$keys = $winners = array_keys( $result);

// $i is the current index into each competitor's array
// $j is the current index into the $keys array (telling us the current competitor)
// $k is the next index into the $keys array (telling us the next competitor, i.e. the competitor to compare the current competitor with)
for( $i = 0; $i < $num_elements; $i++) {

    // If we've eliminated all but one winner, we're done!
    if( count( $winners) == 1) { 
        $finish_order[] = array_pop( $winners);
        break;
    }

    echo 'Element number ' . $i . "\n";

    for( $j = 0; $j < $num_competitors; $j++) {

        // If we've already eliminated this competitor, continue;
        if( !isset( $winners[$j])) continue;

        for( $k = $j + 1; $k < $num_competitors; $k++) {

            // If we've already eliminated this competitor, continue;
            if( !isset( $winners[$k])) continue;

            echo "\t - Who wins: " . $result[ $keys[$j] ][$i] . ' from ' . $keys[$j] . ' or ' . $result[ $keys[$k] ][$i] . ' from ' . $keys[$k] . "?\n";

            if( $result[ $keys[$j] ][$i] < $result[ $keys[$k] ][$i]) {

                echo "\t\t *** " . $keys[$k] . ' is out!' . "\n";
                $finish_order[] = $keys[$k];                
                unset( $winners[$k]);
            }

            if( $result[ $keys[$j] ][$i] > $result[ $keys[$k] ][$i]) {

                echo "\t\t *** " . $keys[$j] . ' is out!' . "\n";
                $finish_order[] = $keys[$j];                
                unset( $winners[$j]);
            }

        }
    }
}

echo "Game over - Result order is: " . implode( ', ', array_reverse( $finish_order));

Output:

Element number 0
     - Who wins: 1 from a or 1 from b?
     - Who wins: 1 from a or 2 from c?
         *** c is out!
Element number 1
     - Who wins: 3 from a or 2 from b?
         *** a is out!
Game over - Result order is: b, a, c

Demo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.