I am trying to calculate the winning order of golfers when they are tied in a competition.
These golf competitions are using the "stableford" points scoring system, where you score points per hole with the highest points winning. Compared to normal golf "stroke play" where the lowest score wins (though this also has the countback system, only calculating the lowest score in the event of a tie...)
The rules are to use a "countback". i.e., if scores are tied after 9 holes, the best placed of the ties is the best score from the last 8 holes. then 7 holes, etc.
The best I can come up with is 2 arrays.
An array with all the players who tied in a given round. ($ties)
One which has the full score data in (referencing the database playerid) for all 9 holes. ($tie_perhole)
I loop through array 1, pulling data from array 2 and using the following formula to create a temporary array with the highest score:
$max = array_keys($array,max($array));
If $max only has 1 item, this player is the highest scorer. the loop through the first array is "by reference", so on the next iteration of the loop, his playerid is now longer in the array, thus ignored. this continues until there is only 1 playerid left in the first array.
However, it only works if a single player wins in each iteration. The scenario that doesn't work is if a sub-set of players tie on any iterations / countbacks.
I think my problem is the current structure I have will need the original $ties array to become split, and then to continue to iterate through the split arrays in the same way...
As an example...
The $ties array is as follows:
Array
(
[18] => Array
(
[0] => 77
[1] => 79
[2] => 76
[3] => 78
)
)
The $tie_perhole (score data) array is as follows:
Array
(
[18] => Array
(
[77] => Array
(
[9] => 18
[8] => 16
[7] => 14
[6] => 12
[5] => 10
[4] => 8
[3] => 6
[2] => 4
[1] => 2
)
[79] => Array
(
[9] => 18
[8] => 17
[7] => 15
[6] => 14
[5] => 11
[4] => 9
[3] => 7
[2] => 5
[1] => 3
)
[76] => Array
(
[9] => 18
[8] => 16
[7] => 14
[6] => 12
[5] => 10
[4] => 8
[3] => 6
[2] => 4
[1] => 2
)
[78] => Array
(
[9] => 18
[8] => 17
[7] => 15
[6] => 13
[5] => 11
[4] => 9
[3] => 7
[2] => 5
[1] => 3
)
)
)
So in this competition, player's 78 and 79 score highest on the 8th hole countback (17pts), so 1st and 2nd should be between them. Player 79 should then be 1st on the 6th hole countback (14pts, compared to 13pts). The same should occur for 3rd and 4th place with the 2 remaining other players.
There are other scenarios that can occur here, in that within a competition, there will likely be many groups of players (of different amounts) on different tied points through the leaderboard.
Also note, there will be some players on the leaderboard who are NOT tied and stay in their current outright position.
The basics of the working code I have is:
foreach ($ties as $comparekey => &$compareval) {
$tie_loop = 0;
for ($m = 9; $m >= 1; $m--) {
$compare = array();
foreach ($compareval as $tie) {
$compare[$tie] = $tie_perhole[$comparekey][$tie][$m];
}
$row = array_keys($compare,max($compare));
if (count($row) == 1) {
$indexties = array_search($row[0], $ties[$comparekey]);
unset($ties[$comparekey][$indexties]);
// Now update this "winners" finishing position in a sorted array
// This is a multidimensional array too, with custom function...
$indexresults = searchForId($row[0], $comp_results_arr);
$comp_results_arr[$indexresults][position] = $tie_loop;
$tie_loop++;
}
// I think I need conditions here to filter if a subset of players tie
// Other than count($row) == 1
// And possibly splitting out into multiple $ties arrays for each thread...
if (empty($ties[$comparekey])) {
break;
}
}
}
usort($comp_results_arr, 'compare_posn_asc');
foreach($comp_results_arr as $row) {
//echo an HTML table...
}
Thanks in advance for any helpful insights, tips, thoughts, etc...
Robert Cathay asked for more scenarios. So here is another...
The leaderboard actually has more entrants (player 26 had a bad round...), but the code i need help with is only bothered about the ties within the leaderboard.
Summary leaderboard:
Points Player
21 48
21 75
20 73
20 1
13 26
This example produces a $tie_perhole array of:
Array
(
[21] => Array
(
[75] => Array
(
[9] => 21
[8] => 19
[7] => 16
[6] => 14
[5] => 12
[4] => 9
[3] => 7
[2] => 5
[1] => 3
)
[48] => Array
(
[9] => 21
[8] => 19
[7] => 16
[6] => 13
[5] => 11
[4] => 9
[3] => 8
[2] => 5
[1] => 3
)
)
[20] => Array
(
[73] => Array
(
[9] => 20
[8] => 18
[7] => 16
[6] => 13
[5] => 11
[4] => 8
[3] => 6
[2] => 5
[1] => 3
)
[1] => Array
(
[9] => 20
[8] => 17
[7] => 16
[6] => 14
[5] => 12
[4] => 9
[3] => 7
[2] => 4
[1] => 2
)
)
)
In this example, the array shows that players 75 and 48 scored 21 points that player 75 will eventually win on the 6th hole countback (14pts compared to 13pts) and player 48 is 2nd. In the next tied group, players 73 and 1 scored 20 points, and player 73 will win this group on the 8th hole countback and finishes 3rd (18 pts compared to 17 pts), with player 1 in 4th. player 26 is then 5th.
Note, the $tie_loop is added to another array to calculate the 1st to 5th place finishing positions, so that is working.
Hopefully that is enough to help.
Ok, so I don't understand golf at all... hahaha BUT! I think I got the gist of this problem, so heres my solution.
<?php
/**
* Author : Carlos Alaniz
* Email : Carlos.glvn1993#gmail.com
* Porpuse : Stackoverflow example
* Date : Aug/04/2015
**/
$golfers = [
"A" => [1,5,9,1,1,2,3,4,9],
"B" => [2,6,4,2,4,4,1,9,3],
"C" => [3,4,9,8,1,1,5,1,3],
"D" => [1,5,1,1,1,5,4,5,8]
];
//Iterate over scores.
function get_winners(&$golfers, $hole = 9){
$positions = array(); // The score numer is the key!
foreach ($golfers as $golfer=>$score ) { // Get key and value
$score_sub = array_slice($score,0,$hole); // Get the scores subset, first iteration is always all holes
$total_score = (string)array_sum($score_sub); // Get the key
if(!isset($positions[$total_score])){
$positions[$total_score] = array(); // Make array
}
$positions[$total_score][] = $golfer; // Add Golpher to score.
}
ksort($positions, SORT_NUMERIC); // Sort based on key, low -> high
return array(end($positions), key($positions)); // The last shall be first
}
//Recursion is Awsome
function getWinner(&$golfers, $hole = 9){
if ($hole == 0) return;
$winner = get_winners($golfers,$hole); // Get all ties, if any.
if(count($winner[0]) > 1){ // If theirs ties, filter again!
$sub_golfers =
array_intersect_key($golfers,
array_flip($winner[0])); // Only the Worthy Shall Pass.
$winner = getWinner($sub_golfers,$hole - 1); // And again...
}
return $winner; // We got a winner, unless they really tie...
}
echo "<pre>";
print_R(getWinner($golfers));
echo "</pre>";
Ok... Now ill explain my method...
Since we need to know the highest score and it might be ties, it makes no sense to me to maintain all that in separate arrays, instead I just reversed the
golfer => scores
to
Tota_score => golfers
That way when we can sort the array by key and obtain all the golfers with the highest score.
Now total_score is the total sum of a subset of the holes scores array. So... the first time this function runs, it will add all 9 holes, in this case theres 3 golfers that end up with the same score.
Array
(
[0] => Array
(
[0] => A
[1] => B
[2] => C
)
[1] => 35
)
Since the total count of golfers is not 1 and we are still in the 9th hole, we run this again, but this time only against those 3 golfers and the current hole - 1, so we are only adding up to the 8th hole this time.
Array
(
[0] => Array
(
[0] => B
[1] => C
)
[1] => 32
)
We had another tie.... this process will continue until we reach the final hole, or a winner.
Array
(
[0] => Array
(
[0] => C
)
[1] => 31
)
EDIT
<?php
/**
* Author : Carlos Alaniz
* Email : Carlos.glvn1993#gmail.com
* Porpuse : Stackoverflow example
**/
$golfers = [
"77" => [2,4,6,8,10,12,14,16,18],
"79" => [3,5,7,9,11,14,15,17,18],
"76" => [2,4,6,8,10,12,14,16,18],
"78" => [3,5,7,9,11,13,15,17,18]
];
//Iterate over scores.
function get_winners(&$golfers, $hole = 9){
$positions = array(); // The score numer is the key!
foreach ($golfers as $golfer => $score) { // Get key and value
//$score_sub = array_slice($score,0,$hole); // Get the scores subset, first iteration is always all holes
$total_score = (string)$score[$hole-1]; // Get the key
if(!isset($positions[$total_score])){
$positions[$total_score] = array(); // Make array
}
$positions[$total_score][] = $golfer; // Add Golpher to score.
}
ksort($positions, SORT_NUMERIC); // Sort based on key, low -> high
return [
"winner"=> end($positions),
"score" => key($positions),
"tiebreaker_hole" => [
"hole"=>$hole,
"score"=> key($positions)],
]; // The last shall be first
}
//Recursion is Awsome
function getWinner(&$golfers, $hole = 9){
if ($hole == 0) return;
$highest = get_winners($golfers,$hole); // Get all ties, if any.
$winner = $highest;
if(count($winner["winner"]) > 1){ // If theirs ties, filter again!
$sub_golfers =
array_intersect_key($golfers,
array_flip($winner["winner"])); // Only the Worthy Shall Pass.
$winner = getWinner($sub_golfers,$hole - 1); // And again...
}
$winner["score"] = $highest["score"];
return $winner; // We got a winner, unless they really tie...
}
echo "<pre>";
print_R(getWinner($golfers));
echo "</pre>";
Result:
Array
(
[winner] => Array
(
[0] => 79
)
[score] => 18
[tiebreaker_hole] => Array
(
[hole] => 6
[score] => 14
)
)
Actually my date is $Date= '03/02/2015';
I want to increment this day with array of days .My array is
Array ( [0] => 1 [1] => 42 [2] => 70 [3] => 98 [4] => 186 [5] => 279 [6] => 372 [7] => 465 [8] => 558 [9] => 730 [10] => 1460 [11] => 4380 [12] => 1825 ).
I stored this array in a variable called $data.I want to increment my date with each of this days and print all result dates.How can i do it???
Try this with this code you can print dates
<?php
$Date = "2015-02-03";
$dataArray = Array ( 1 ,42 , 70 , 98 , 186 , 279 ,372);
foreach($dataArray as $val){
echo date('Y-m-d', strtotime($Date. " + $val days"))."</br>";
}
?>
Use this code
<?php
$Date= '03/02/2015';
$stamp= strtotime($Date);
$days=array(42,70,98,186,279,372,465,558,730,1460,4380,1825); //change these values
$values=array();
foreach($days as $day){
$newstamp=$stamp+($day*24*60*60);
$values[]=date("m/d/Y",$newstamp);
}
//now add to database
mysql_connect('localhost','user','pass'); //change user pass
mysql_select_db('yourdatabase'); //change here
foreach($values as $value) {
$sql="insert into yourtable values('".$value."',xxx,xxxx..))"; //change here
mysql_query($sql);
}
mysql_close();
?>
I'm currently working on a friendshipsystem. To accept a friend I need to get the friendship_id value.
Based on the email (from the session) I can get a lot of information, such as surname, name, photo, ID NUMBER,... from the specific friendshiprequest
I can print the information for each friendship in this way. So I have the FRIENDSHIP ID VALUE TO DISPLAY AS INFORMATION but now I want to use it in a function.
$friendrequests=$friendship->GetAllFriendRequests($email);
<?php
foreach ($friendrequests as $request) {
echo "
<div><p>
<a href='profile.php?user_id=".$request['friendship_applicant_id'] . "'>
<img src='uploads/" . $request['friendship_applicant_avatar'] . " " . " ' alt='' />" . $request['friendship_applicant_surname'] . $request['friendship_id'] . " " . $request['friendship_applicant_name'] . "
</a> has send you a friend request" . "
<form action='" . $_SERVER['REQUEST_URI'] . "' method='post'>
<button type='submit' name=''>Accept</button>
<button type='submit' name=''>Decline</button>
</form>
</p></div>";
}
?>
So i tried to get the specific number with the following code, but it says undefined index for friendship_id: $friendrequestnumber = $friendrequests['friendship_id'];
This is the code the GetAllFriendRequests function. Can I use this code or should I do it in a totally different way?
public function GetAllFriendRequests($email) {
$db = new Db();
$select = "SELECT * FROM friendship WHERE friendship_recipient = '" . $email . "' AND friendship_status = 'pending' ORDER BY friendship_id DESC";
$result = $db -> conn -> query($select);
$result_array=array();
while ($row = mysqli_fetch_array($result)) {
$result_array[]=$row;
}
return $result_array;
}
With a var_dump I get this information of the 2 requests:
Array ( [0] => Array ( [0] => 84 [friendship_id] => 84 [1] => ron#hot.com [friendship_applicant] => ron#hot.com [2] => 29 [friendship_applicant_id] => 29 [3] => ron [friendship_applicant_name] => ron [4] => ron [friendship_applicant_surname] => ron [5] => 1394134610fuckyou.jpg [friendship_applicant_avatar] => 1394134610fuckyou.jpg [6] => jan#hot.com [friendship_recipient] => jan#hot.com [7] => 1 [friendship_recipient_id] => 1 [8] => Vandenbergh [friendship_recipient_name] => Vandenbergh [9] => Jan [friendship_recipient_surname] => Jan [10] => 1394041001fuckyou.jpg [friendship_recipient_avatar] => 1394041001fuckyou.jpg [11] => Pending [friendship_status] => Pending [12] => 0000-00-00 00:00:00 [friendship_time] => 0000-00-00 00:00:00 ) [1] => Array ( [0] => 78 [friendship_id] => 78 [1] => Bert#hot.com [friendship_applicant] => Bert#hot.com [2] => 2 [friendship_applicant_id] => 2 [3] => Van Damme [friendship_applicant_name] => Van Damme [4] => Bert [friendship_applicant_surname] => Bert [5] => sdfds.png [friendship_applicant_avatar] => sdfds.png [6] => Jan#hot.com [friendship_recipient] => Jan#hot.com [7] => 1 [friendship_recipient_id] => 1 [8] => Vandenbergh [friendship_recipient_name] => Vandenbergh [9] => Jan [friendship_recipient_surname] => Jan [10] => 1394041001fuckyou.jpg [friendship_recipient_avatar] => 1394041001fuckyou.jpg [11] => Pending [friendship_status] => Pending [12] => 0000-00-00 00:00:00 [friendship_time] => 0000-00-00 00:00:00 ) )
From your var_dump, $friendrequests is a nested array. So you need to use a loop to iterate over all values like in the case above where $request['friendship_id'] can use it or if you simply want the first value, use $friendrequests[0]['friendship_id']
I have data in the following form
Array
(
[0] => Array
(
[event_id] => 2042632
[event_name] => Georgia Tech Yellow Jackets vs. North Carolina Tar Heels
[event_payment] => 156
[payment_status] => 1
[event_date] => 2014-01-29
)
[1] => Array
(
[event_id] => 2042632
[event_name] => Georgia Tech Yellow Jackets vs. North Carolina Tar Heels
[event_payment] => 89
[payment_status] => 1
[event_date] => 2014-01-29
)
[2] => Array
(
[event_id] => 2042632
[event_name] => Georgia Tech Yellow Jackets vs. North Carolina Tar Heels
[event_payment] => 772
[payment_status] => 1
[event_date] => 2014-01-29
)
[3] => Array
(
[event_id] => 2042633
[event_name] => Georgia Tech Yellow Jackets vs. North Carolina Tar Heels
[event_payment] => 256
[payment_status] => 0
[event_date] => 2013-12-29
)
)
All I want now to show data in the following format after getting from this array:
January
Event-name, payment, status
georgia.. 1234, 0
georgia.. 3456, 1
December
Event-name, payment, status
georgia.. 1234, 0
georgia.. 3456, 1
and so on and so forth.
please guide me how to do that..
Try
$result = array();
foreach($arr as $ar){
$date = DateTime::createFromFormat("Y-m-d", $ar['event_date']);
$month = $date->format('F');
$year = $date->format('Y');
$result[$year][$month][] = $ar;
}
See demo here
$res= array();
foreach($arr as $key => $val) // $arr is your actual array
{
$month = date('F-Y', strtotime($val['event_date']));
$res[$month][] = $val;
}
Now you get will result as
[January-2014] = array(a1,a2...)
[December-2014] = array(a1,a2...)
Here I only suggest how to sort an array by date. I hope you can do the rest of the work yourself.
function cmp($a, $b) {
return (new DateTime($a['event_date']))->getTimestamp() < (new DateTime($b['event_date']))->getTimestamp()? -1 : 1;
}
usort($array, 'cmp');
$curr_month = 0;
foreach ($array as $elem) {
// output elements of array based on month
// ...
}