Calculate soccer matches combinations without repetition - php

So, I have an array like this, filled with teams:
array(0, 1, 2, 3, 4, 5, ...)
At every tournament, we have TotalNumberOfTeams-1 rounds (dates) with matches. (1st loop)
At every round, we have TotalNumberOfTeams/2 matches. (2 loop)
How is possible to calculate the combinations for this result:
Date Date Date Date Date
Match: 0-1 0-2 0-3 0-4 0-5
Match: 2-3 1-5 1-4 1-3 1-2
Match: 4-5 3-4 2-5 2-4 3-5
/w common words: Every team plays every round with different team
Code to calculate rounds, matches and dates:
// Rounds
for($i=1; $i <= ($teamsNum - 1); $i++) {
// Matches
for($z=0; $z < ($teamsNum / 2); $z++){
//some code here
}
// Calculate next date
$mdate = date('Y-m-d', strtotime($mdate. ' + x days'));
}

Use round-robin tournament algorithm.
In short:
Make two rows of commands, every top command plays with corresponding command form lower row. I number is odd, one command rests.
Shift all command except for the first in circular manner
0 1
2 3
=====
0 2
3 1
====
0 3
1 2

there is an answer with code example - http://rosettacode.org/wiki/Combinations#php
just use $k=2 for yours calculations

Related

How To Get Concatenate Number Or String PHP With Long Consecutive Numbers In PHP?

So I want to get number with Consecutive Numbers like below.
1234567891011121314151617181920212223..............
when i input 10 then output is 1. and so on like below.
10th digit is 1
11th digit is 0
12th digit is 1
13th digit is 1
14th digit is 1
15th digit is 2
16th digit is 1
17th digit is 3
This is my code to make Consecutive Numbers. Its work as i want expected.
<?php
$i=1;
$urut='';
$a = $_GET['button1'];
echo "Your number ", $a, "<br>";
while ($i<=$a){
$urut=$urut.''.$i;
$i++;
}
$pecah = str_split($urut,1);
echo "Urut angka ke ".$a."adalah ". $pecah[$a-1];
?>
But my case is how to get number when Consecutive up to 1 million or more.
I tried that but when set 1 millions or more its load very long time and cant show the result number
You'll probably need to do something like calculating the length of each range of numbers.
For example you know that:
1 through 9 are 1 character
10 through 99 are 2 characters
100 through 999 are 3 characters
And so on
Doing so will allow you to calculate the length of the string up to a certain number.
For example the amount of characters before 1000 can be calculated like so.
9x1 + (99 - 10) x 2 + (999 - 100) x 3
Using this you can distil a formula which allows you to calculate the value for any given number.

Is there any algorithm to make round robin schedule having each round unique combinations?

Suppose I have an array of 10 participants [1,2,3,4,5,6,7,8,9,10]
Assuming a league, as there are 10 participants, so each participant will have 9 matches with other 9 participants.
Therefore, there will be 9 rounds having single matches for each participant. For example-
Round 1: 1-2, 3-4, 5-6, 7-8, 9-10 [no repeat for any participant]
Round 2: 1-3, 2-4, 5-7, 8-9, 6-10 [no repeat for any participant]
and so on..
Is there any mathematical algorithmic solution/pattern there?
I would like to avoid array push/pop method if possible.
Yes, there is rather simple algorithm to generate all possible pairs ((N-1)*N/2)
Put items into two rows.
At every round player from the top row plays with corresponding player from bottom row.
Fix the first one.
Shift all others in cyclic manner.
Note that you can work with indexes of array, not changing it's contents
A B
D C
pairs A-D, B-C
A D
C B
pairs A-C, D-B
A C
B D
pairs A-B, C-D
My naive implementation in PHP (ideone) outputs indexes of players:
function GenPairs($N) {
for ($i=0; $i<$N-1;$i++){
echo(0).":";
echo($N - 1 - $i)."\n";
for ($j=1; $j<$N/2;$j++){
echo(1 + (($N - $i + $j - 2) % ($N - 1))).":";
echo(1 + ((2*$N - $i - $j - 3) % ($N - 1)))."\n";
}
echo("\n");
}
}
GenPairs(6);
0:5
1:4
2:3
0:4
5:3
1:2
0:3
4:2
5:1
0:2
3:1
4:5
0:1
2:5
3:4

Identity the available range numbers when two range numbers are overlap

If I have an existing range:
1-10
11-50
Then I will enter a new range from 1 - 60, How could I detect that the new range to be added overlaps to the previous entries? And how can I get the available range? In this case the available range is from 51-60.
Does anyone here have a great idea on this?
Thanks for helping.
Here's my current code:
$saved = array(
array(
"start" => 1,
"end" => 10
),
array(
"start" => 10,
"end" => 50
)
);
$new_range = array(
"start" => 1,
"end" => 60
);
$usable_range = array();
$previous_from = 0;
$previous_to = 0;
foreach($saved as $value)
{
$range_start = 0;
$range_end = 0;
if($previous_from<$value['start'])
{
$previous_from = $value['start'];
}
if($previous_to<$value['end'])
{
$previous_to = $value['end'];
}
if($previous_from<=$new_range['start'])
{
if($previous_to<$new_range['end'])
{
$range_start = $previous_to+1;
$range_end = $new_range['end'];
$new_range['start'] = $range_start;
}
}
else if($previous_from>=$new_range['start'])
{
if($previous_to<$new_range['end'])
{
$range_start = $previous_to+1;
$range_end = $new_range['end'];
$new_range['start'] = $range_start;
}
}
$usable[] = array("range_start"=>$range_start,"range_end"=>$range_end);
}
Call every interval (min,max)
1) Sort your list of intervals by their min.
2) Check to see if any max is greater than the next entry over's min. If they are, create the interval that is the smaller of their mins and the greater of their maxes, and add it back into the list in place of those two.
3) Whenever you get a new interval, binary search into the list to add it, sorted by min. Then, using similar logic as in 2), attempt to merge it with the entry one below and one above until no more merges are possible.
EDIT: A few changes.
First, since we're using integers not floats, if you have an interval like 1,10 and 11,20 then there is no 'gap' between the 10 and 11 - so we should consider this to be one larger interval, 1,20. Reflect this by, instead of checking to see if max > next min, if max >= next min - 1.
Second, if you want to find all intervals formed by overlap when merging a new interval into your list of intervals:
1) Since your list of intervals is known to be in a state where it is sorted by min and also sorted by max, binary search into it to find the lowest min just above your new min and the highest max just above your new max.
2) Iterate over min, max, min, max... etc in your array that are between your new min and new max. Below the lowest min, above the highest max and between each max/min you can compute the interval that is in the 'gap' there, and return them in e.g. an array.
For example if your list of intervals contains 13,16, 21,24 and 31, 38 and you want to calculate the non-overlap of the new interval 1,30:
1) We binary search into our list and find that 13 is the lowest min above 1 and 24 is the highest max above 30.
2) We iterate like so:
Between our min and the lowest min is 1 and 13 - so this forms an interval 1,12 (inclusive bottom, exclusive top). Add onto the return array.
Between max and the next min is 16 and 21 - so this forms an interval 17,20 (exclusive on both ends). Add onto the return array.
Between max and our max is 24 and 30 - so this forms an interval 25,30 (exclusive bottom, inclusive top). Add onto the return array.
Finding overlap can be described as finding an intersection. Likewise finding the available range can be described as finding the difference. One way of doing this would be treating these sets as arrays and using the array_intersect [1] and array_diff [2] functions.
That is all I can come up with given your details.
[1] - http://php.net/manual/en/function.array-intersect.php
[2] - http://www.php.net/manual/en/function.array-diff.php

How to sort an array by value in a certain order?

Given an array of any size (from 1 to 4 rounds) with ranks numbering from 1 to 8 (or more), how can I take that array and sort it bracket style, so rank 1 is first, rank 2 is last, then rank 8 is next, then rank 7 is second to last... like
Then the next round ..
1, 4, 3, 2
I am trying to sort tournament brackets but not having much luck when it comes to sorting the ranking, and also in a way that scales well so the display does not break.
Edit:
Some clarification, each bracket size needs to break down like so:
If the bracket has 8 games, the game numbers are 1 through 8, so that round needs to arrange itself like:
Game 1
Game 8
Game 5
Game 4
Game 6
Game 3
Game 7
Game 2
So then, on the next round, it has 4 games, which would come out as:
Game 1
Game 4
Game 3
Game 2
And so on:
Game 1
Game 2
Finally,
Game 1
It also needs to work if the starting bracket had 16 games instead of 8, or 32, or more. The idea is that the winner of Game 1 and Game 8 play each other in Game 1 on the next round. The first game and second game are always the first and last on each bracket. Then it works it's way inward.
This isn't sorting the list. Unless you really need to sort the list, indices may be faster and more efficient.
The match ups will be set up like (current_rank), (total ranks) - (current_rank) + 1
Since there are 8 ranks,
1, 8 -1 +1 = 8
2, 8 -2 +1 = 7
3, 8 -3 +1 = 6
4, 8 -4 +1 = 5
So the code would look something like
<?php
$rankscount = count($ranks);
for ($i = 1; $i <= $rankscount / 2; $i++) {
echo "matchup will be: rank " . $i . " , rank " . $rankscount - $i + 1;
}
?>
After each round, reseed the function with the new sorted list, and you'll get 1vs4. 2vs3.
I'm not a professional at PHP, but hopefully this helps.
The following function sorts an array of ['r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8'] into an order of ['r1', 'r8', 'r2', 'r7', 'r3', 'r6', 'r4', 'r5'].
An array of ['r1', 'r2', 'r3', 'r4'] will be rearranged into ['r1', 'r4', 'r2', 'r3']
function rearranged($array) {
sort($array);
$result = array();
$length = count($array);
$offset = 0;
// Handling two elements at once, therefore just do $lenght/2 iterations
for ($i = 0; $i < $length/2; $i++) {
// $i + $offset: The current element in the original array
// + the offset of fields already filled in the results array
$result[$i + $offset] = $array[$i];
// $i + 1 + $offset: The next element in the results array
$result[$i + 1 + $offset] = $array[$length - $i -1];
// Increment offset
$offset++;
}
return $result;
}
I am not using any inbuilt sort function since they compare all keys to each others, assuming that your array already is in order just iterating and swapping positions should be much faster. If the keys are not ordered you can call a inbuilt sort function such as sort(sorts by value) or ksort (sorts by key).
To note is as well, that this function only works properly for arrays with an even amount of elements. If the number of elements is uneven the last element will be dropped from the results array.

PHP round up list items to nearest five

I've got a grid of 10 square list items. A bit like a gallery. If the user adds another item there will be 11. However this will look strange as the 11th item will be on its own in a new row. How can I use PHP to round up to the nearest 5 and add in the some blank/dummy list items?
You could use the modulo operator to identify the remainder of a division:
10 % 5 = 0
11 % 5 = 1
12 % 5 = 2
13 % 5 = 3
14 % 5 = 4
15 % 5 = 0
With that you can identify if (and how large) such an uncomplete row would be. Knowing how many elements are in that last uncomplete row oviously allows you to calculate the number of remaining cells to fill the row.
($y+(($y%$x)?($x-($y%$x)):0))
...where $y is the number of items(e.g. 11) and $x is the number of items in a row(e.g. 5)

Categories