I’m having trouble figuring out how to solve this question, it’s from a free online test website. Here’s the link: https://www.testdome.com/questions/php/league-table/19939?questionIds=7278,19939&generatorId=30&type=fromtest&testDifficulty=Hard
But to be clearer, I’m writing the question and my answer as well. The starting answer is there in the link written above.
Question:
The LeagueTable class tracks the score of each player in a league. After each game, the player records their score with the recordResult function.
The player’s rank in the league is calculated using the following logic:
The player with the highest score is ranked first (rank 1). The player with the lowest score is ranked last. If two players are tied on score, then the player who has played the fewest games is ranked higher. If two players are tied on score and number of games played, then the player who was first in the list of players is ranked higher. Implement the playerRank function that returns the player at the given rank.
For example:
$table = new LeagueTable(array('Mike', 'Chris', 'Arnold')); $table->recordResult('Mike', 2); $table->recordResult('Mike', 3); $table->recordResult('Arnold', 5); $table->recordResult('Chris', 5); echo $table->playerRank(1);
All players have the same score. However, Arnold and Chris have played fewer games than Mike, and as Chris is before Arnold in the list of players, he is ranked first. Therefore, the code above should display “Chris”.
My code:
<?php class LeagueTable { public function __construct($players) { $this->standings = array(); foreach($players as $index => $p) { $this->standings[$p] = array ( 'index' => $index, 'games_played' => 0, 'score' => 0 ); } } public function recordResult($player, $score) { $this->standings[$player]['games_played']++; $this->standings[$player]['score'] += $score; } public function playerRank($rank) { // I'm not sure what to do in here, not even sure where to place the conditional statements // but here's me trying to figure it out which I'm 90% sure I'm doing it wrong, // since I'm using too many foreach function and arrays. Most probably not even close // to the correct answer. $comparison = $result = $this->standings; $player_names = array(); foreach($this->standings as $name => $records) { foreach($comparison as $name_compare => $records_compare) { if($this->standings[$name]['score'] > $comparison[$name_compare]['score']) { $result[$name]['index'] = $this->standings[$name]['index']; } else if($this->standings[$name]['score'] == $comparison[$name_compare]['score'] && $this->standings[$name]['games_played'] < $comparison[$name_compare]['games_played']) { $result[$name]['index'] = $this->standings[$name]['index']; } else if($this->standings[$name]['score'] == $comparison[$name_compare]['score'] && $this->standings[$name]['games_played'] == $comparison[$name_compare]['games_played']) { $result[$name]['index'] = $this->standings[$name]['index']; } // This is where I'm confused, although there are conditional statemens there // but the code inside each "if" and "else if" is the same. } } foreach($result as $name => $records) { array_push($player_names,$name); } return $player_names[$rank-1]; //This should return "Chris" based on the record result, but it's not } } $table = new LeagueTable(array('Mike', 'Chris', 'Arnold')); $table->recordResult('Mike', 2); $table->recordResult('Mike', 6); $table->recordResult('Arnold', 5); $table->recordResult('Chris', 5); echo $table->playerRank(1);
Can anybody helps me solve this question please?
Advertisement
Answer
Using usort in your case
usort($this->standings, function($a, $b) { // Compare scores $r = $b['score'] - $a['score']; // If two players are tied on score, // then the player who has played the fewest games is ranked higher if(! $r) { $r = $a['games_played'] - $b['games_played']; } // If two players are tied on score and number of games played, // then the player who was first in the list of players is ranked higher if(! $r) { $r = $a['index'] - $b['index']; } return $r; }); // You can watch result of sorting print_r($this->standings);