php modulo and print_r of the result? - php

i wanted to make my own quarter-final draw for the champion's league (tomorrow, friday 16 of march) : i've got 2 questions : first the modulo does not work : it shows "another match" after every entry in the array, whereas i wanted it to be written every two matches (every 2 entries)...
Second question : is there a better way to "print" the result? like a print_r without the index and where i could say "add \n after each entry" ?
<body>
<?php
$array = array("real", "barça", "bayern", "apoel", "chelsea", "milan", "benfica", "marseille" );
$new = array();
$incr = count($array);
while($incr>0){
$random = rand(0, count($array));
if (!in_array($array[$random], $new)){
$new[] = $array[$random];
if ( (count($new) % 2) ){
$new[] = " -- another match : ";
}
$incr--;
}
}
print_r($new);
?>
<p>results</p>
</body>
Thanks for your help

Another option would be to shuffle the array then just pop off each of the elements
$array = array("real", "barça", "bayern", "apoel", "chelsea", "milan", "benfica", "marseille" );
shuffle($array);
while($a = array_pop($array)) {
echo $a." vs. ".array_pop($array)." <br />";
}
Sample output:
apoel vs. real
barça vs. milan
marseille vs. bayern
chelsea vs. benfica

The modulo is working perfectly:
The array starts empty.
You add an element to it.
The length is 1, so 1 % 2, so 1, so truthy, so you add -- another match to the array
So the length is now 2
Next iteration of the loop, you add another element to the array.
The length is now 3, so 3 % 2, so 1, so truthy, so you add -- another match
And so on. Whatever it is you're trying to do, it's not what you told the server to do.
What you should probably do is something like this:
$array = Array(........);
while($a = array_shift($array)) {
$random = rand(0,count($array)-1); // -1 is important!
echo $a." vs. ".$array[$random]."<br />";
unset($array[$random)];
// no need to realign keys since array_shift already does that
}

The modulus is working exactly as you're telling it to.
(count($new) % 2) ){
when count($new) = 1, 1 % 2 = 1, = true
when count($new) = 2, 2 % 2 = 0, = false
when count($new) = 3, 3 % 2 = 1, = true
when count($new) = 4, 4 % 2 = 0, = false
when count($new) = 5, 5 % 2 = 1, = true
when count($new) = 6, 6 % 2 = 0, = false

Related

How to efficiently sum paired array elements and avoid offset errors in case of pairless array?

Pair every two arrays is the task – store it, print it and repeat it until it becomes one value.
input : 1, 2, 3, 4, 5, 6, 8, 9, 9
output: 3 7 11 17 9
10 28 9
38 9
47
My code is working fine in this scenario. Somehow I managed to add 0 at the end for pairless elements. But my main focus is how can I make the logic even more clearer to avoid grumpy offset errors?.
My code:
function sumForTwos($arr)
{
if(count($arr) == 1){
exit;
}
else {
$sum = [];
for ($i = 0; $i < count($arr) -1; $i++)
{
//logic to add last array for odd count to avoid offset error
if(count($arr) % 2 == 1){ $arr[count($arr)] = 0; }
//logic to pair arrays
if($i != 0) { $i++; }
$sum = $arr[$i] + $arr[$i + 1];
$total[] = $sum;
echo $sum . " ";
}
echo "<br>";
$arr = $total;
//Recursion function
sumForTwos($arr);
}
}
sumForTwos([1, 2, 3, 4, 5, 6, 8, 9, 9]);
You can adopt an iterative approach and look at this as processing each level of values with every next level have 1 value less from total values. In other words, you can look at this as a breadth first search going level by level. Hence, you can use a queue data structure processing each level one at a time.
You can use PHP's SplQueue class to implement this. Note that we can advantage of this class as it acts as a double-ended queue with the help of below 4 operations:
enqueue - Enqueues value at the end of the queue.
dequeue - Dequeues value from the top of the queue.
push - Pushes value at the end of the doubly linked list(here, queue is implemented as doubly linked list).
pop - Pops a node from the end of the doubly linked list.
Most certainly, all the above 4 operations can be done in O(1) time.
Algorithm:
Add all array elements to queue.
We will loop till the queue size is greater than 1.
Now, if queue level size is odd, pop the last one and keep it in buffer(in a variable).
Add all pairwise elements by dequeueing 2 at a time and enqueue their addition for next level.
After level iteration, add the last element back if the previous level size was odd.
Print those added elements and echo new lines for each level accordingly.
Snippet:
<?php
function sumForTwos($arr){
if(count($arr) == 1){
echo $arr[0];
return;
}
$queue = new SplQueue();
foreach($arr as $val){
$queue->enqueue($val); // add elements to queue
}
while($queue->count() > 1){
$size = $queue->count();
$last = false;
if($size % 2 == 1){
$last = $queue->pop(); // pop the last odd element from the queue to make queue size even
$size--;
}
for($i = 0; $i < $size; $i += 2){
$first = $queue->dequeue();
$second = $queue->dequeue();
echo $first + $second," ";
$queue->enqueue($first + $second);
}
if($last !== false){// again add the last odd one out element if it exists
echo $last; // echo it too
$queue->push($last);
}
echo PHP_EOL;// new line
}
}
sumForTwos([1, 2, 3, 4, 5, 6, 8, 9, 9]);
Demo: http://sandbox.onlinephpfunctions.com/code/5b9f6d4c9291693ac7cf204af42d1f0ed852bdf9
Does this do what you want?
function pairBySums($inputArray)
{
if (sizeof($inputArray) % 2 == 1) {
$lastEntry = array_pop($inputArray); //$inputArray now has even number of elements
}
$answer = [];
for ($ii = 0; $ii < sizeof($inputArray) / 2; $ii++) {
$firstIndexOfPair = $ii * 2; // 0 maps to 0, 1 maps to 2, 3 maps to 4 etc
$secondIndexOfPair = $firstIndexOfPair + 1; // 0 maps to 1, 1 maps to 3, 2 maps to 5 etc
$answer[$ii] = $inputArray[$firstIndexOfPair] + $inputArray[$secondIndexOfPair];
}
if (isset($lastEntry)) {
array_push($answer, $lastEntry);
}
echo implode(' ', $answer) . "<br>";
if (sizeof($answer) > 1) {
pairBySums($answer);
}
}
The algorithm makes sure it operates on an even array and then appends the odd entry back on the array if there is one.
$input = [1, 2, 3, 4, 5, 6, 8, 9, 9];
pairBySums($input);
produces:
3 7 11 17 9
10 28 9
38 9
47
With an even number of items,
$input = [1, 2, 3, 4, 5, 6, 8, 9];
pairBySums($input);
produces:
3 7 11 17
10 28
38

I want to get elements from array in order: three, four, three, four and so on

I want to get elements from an array like this: get first three element, then four elements, then again three elements, and again four, and so on in a loop.
For example:
0 1 2
3 4 5 6
7 8 9
10 11 12 13
and so on....
I tried something like this:
foreach($items as $key => $item) {
if($key <= 2) {
echo 'test';
}
if($key > 2 && $key < 6) {
echo 'other test';
}
if($key > 6 && $key < 9) {
echo 'test';
}
}
However, I don't want to use if() like these, because I don't know how many items will be in the array: it comes from a database.
I think, I need something like array_chunk($items, 3) but for size parameter I need 3 and 4 in loop
Could be like this you can make another array of specifying the number of elements you want in each iteration.
<?php
$number_of_elements = [3,4,3,4];
$your_array = ['a', 'b','c','d','e'];
foreach($number_of_elements as $number){
for($i = 0; $i<=$number; $i++){
$result = $your_array[$i];
print_r($result);
}
print_r('<br>');
}
In JavaScript you can solve your problem using a for loop and the built in slice function of the array.
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
let offset = 0;
for(let i = 0; i < array.length;){
offset = offset === 3 ? 4 : 3;
const subArray = array.slice(i, i + offset);
console.log(subArray);
i += offset;
}

Finding out combinations of x amount of integers to sum a given number

I am trying to figure out how I can loop out possible combinations of a x amount of integers to sum a specifik number.
Let's say, I have number 7 and I need to figure out how I can sum that number with integers in pairs 3.
1+2+4 = 7
3+3+1 = 7
5+1+1 = 7
2+2+3 = 7
Repeated combinations of numbers doesn't interest me, e.g.:
1+2+4 = 7
2+4+1 = 7
4+2+1 = 7
Anyone got any ideas of how I should proceed to reach this result?
Thanks.
Here is the solution for your problem.
function printPartitions($target, $max, $s){
if($target === 0 )
echo $s;
else
{
if($max > 1)
{
printPartitions($target, $max-1, $s);
}
if($max <= $target)
{
printPartitions($target-$max, $max, $max . " " . $s);
}
}
}
printPartitions(5, 5, "<br/>");
You have to specify the $target Value, $max value.
e.g.
printPartitions(7, 7, "<br/>");
It will give you output like:
1 1 1 1 1 1 1
1 1 1 1 1 2
1 1 1 2 2
1 2 2 2
1 1 1 1 3
1 1 2 3
2 2 3
1 3 3
1 1 1 4
1 2 4
3 4
1 1 5
2 5
1 6
7
I've got a solution to my problem. I feel I should defientely share it here, if anyone would ever need it. My solutions is based on this post: https://stackoverflow.com/a/19067884/3293843
<?php
function sampling($chars, $size, $combinations = array()) {
# if it's the first iteration, the first set
# of combinations is the same as the set of characters
if (empty($combinations)) {
$combinations = $chars;
}
# we're done if we're at size 1
if ($size == 1) {
return $combinations;
}
# initialise array to put new values in
$new_combinations = array();
# loop through existing combinations and character set to create strings
foreach ($combinations as $combination) {
foreach ($chars as $char) {
$new_combinations[] = $combination .'#'. $char;
}
}
# call same function again for the next iteration
return sampling($chars, $size - 1, $new_combinations);
}
// example
$chars = array('1', '2', '3','4');
$target = 7;
$maxLengthOfIntegers = 3;
$output = sampling($chars, $maxLengthOfIntegers);
$repeatedEntries = array();
//presenting the output
foreach($output as $out){
$explodeOut = explode('#',$out);
sort($explodeOut);
if(array_sum($explodeOut) == $target){
$sortedPattern = implode('',$explodeOut);
if(!in_array($sortedPattern,$repeatedEntries)){
echo $sortedPattern.'<br/>';
$repeatedEntries[] = $sortedPattern;
}
}
}
?>
Thank you for your time and efforts.
Regards,
Jacob
you can try this algorithm
$ans = array();
for($i=1;$i<=5;$i++)
{
$i1 = 7-$i;
$i2 = intval($i1 - $i);
$value = $i."+".$i1."+".$i2;
$ans = array_unshift($ans,$value);
}
print_r($ans);
hope this helps.. PLease let me know

if multiple random numbers are all equal return true

Im working on some random generator, and it's something like roll a dices, if all dices are returning same numbers than you won a game if not than you try again.
To get six dices i used mt_rand function and for every dice separately, so i have this:
$first = mt_rand(1,6);
$second = mt_rand(1,6);
$third = mt_rand(1,6);
$fourth = mt_rand(1,6);
$fifth = mt_rand(1,6);
$sixth = mt_rand(1,6);
But i don't know how to return if operand for multiple random generated numbers.
If i would use like 2 dices i would just use
if ( $first === $second )
that would return true if first and second dices, both have returned number 2
But how do i use it if i want to echo true if all 6 dices to return number 2 ?
Edit:
number 2 is just an example if i would need only number 2 i know how to do it with array and variable but point is that i need only all numbers to match, it doesn't matter which ones from 1 to 6. And first answer actually works but let's see if it's possible to do with array.
Use arrays to make your life easier (e.g. $dices with indices from 0 to 5)
Just put it in a loop and check at every iteration. If one dice isn't 2, $allDicesSameNumber wil be false.
$number = mt_rand(1, 6);
$allDicesSameNumber = true;
for ($i = 1; $i < 6 /* dices */; $i++) {
$dices[$i] = mt_rand(1, 6);
if ($dices[$i] !== $number)
$allDicesSameNumber = false;
}
$diceCount = 6;
$diceArray = array();
for($i=1; $i<=$diceCount; $i++) {
$diceArray[] = mt_rand(1,6);
}
if (count(array_count_values($diceArray) == 1) {
echo 'All the dice have the same number';
}

Iterate (loop) through complicated range of numbers using groups to generate Bracket Sheet

I'm trying to build an algorithm for processing bracket sheet of competitions. I need to go through a range of numbers. For each number there will be the athlete name. Numbers are assigned to athletes randomly but the number's pairing must always stay the same. There are two groups odd and even, i.e. A and B.
The only problem that I can't find the proper algorithm to iterate numbers the exact way as follows:
Group A:
--------
1
17
9
25
------
5
21
13
29
------
3
19
11
27
------
7
23
15
31
Group B:
--------
2
18
10
26
------
6
22
14
30
------
4
20
12
28
------
8
24
16
32
Could someone please help with advice or example of how to get the output above?
EDIT 1:
The example above is the bracket sheet for 32 athletes! Same logic must be applied if you use a sheet for 4,8,16,64 or 128 athletes!
EDIT 2:
Let's make it more clear with examples of the sheet for 4 athletes and then the sheet for 16 athletes.
The sheet for 4 athletes:
Group A:
--------
1
3
Group B:
--------
2
4
The sheet for 16 athletes:
Group A:
--------
1
9
5
13
------
3
11
7
15
Group B:
--------
2
10
6
14
------
4
12
8
16
EDIT 3:
The last part, is that I'm planning to have an array with athlete name and its status in it.
By status I mean that, if the athlete has been a champion previously (strong), then he/she gets 1 for status, if the athlete's previous achievements are not known or minimal (weak), then the status is 0. It's done that way, so we could separate strongest athletes into different groups and make sure that they will not fight against each other in the first fight but rather meet each other closer to the semi-final or final.
Example of PHP array:
$participants = array(
array("John", 0),
array("Gagan", 0),
array("Mike Tyson", 1),
array("Gair", 0),
array("Gale", 0),
array("Roy Johnes", 1),
array("Galip", 0),
array("Gallagher", 0),
array("Garett", 0),
array("Nikolai Valuev", 1),
array("Garner", 0),
array("Gary", 0),
array("Gelar", 0),
array("Gershom", 0),
array("Gilby", 0),
array("Gilford", 0)
);
From this example we see that those, who have status 1 must be in different groups, i.e. A and B. But we have only two groups of numbers odd and even and in this example, there are 3 strong athletes. Thus two of them will be at the same group. The final result must be, that those two strong athletes, that got in the same group, must not meet at the very first fight (it means that they will not be on the same pair of numbers and as far away from each other as possible, so they wouldn't meet on the second fight as well).
Then randomly, I'm planning to rearrange the array and send athletes to the bracket sheet - every time, with different numbers, every time, those that have a flag 1 go to different groups and/or never meet at the first fight and every time, athletes' names assigned to the same pair of numbers.
Considering the number of participants is always a power of 2, this piece of code should give you the order you're expecting.
function getOrder($numberOfParticipants) {
$order = array(1, 2);
for($i = 2; $i < $numberOfParticipants; $i <<= 1) {
$nextOrder = array();
foreach($order as $number) {
$nextOrder[] = $number;
$nextOrder[] = $number + $i;
}
$order = $nextOrder;
}
return $order; // which is for instance [1, 17, 9, 25, and so on...] with 32 as argument
}
About the way it works, let's take a look at what happens when doubling the number of participants.
Participants | Order
2 | 1 2
4 | 1 3=1+2 2 4=2+2
8 | 1 5=1+4 3 7=3+4 2 6=2+4 4 8=4+4
... |
N | 1 X Y Z ...
2N | 1 1+N X X+N Y Y+N Z Z+N ...
The algorithm I used is the exact same logic. I start with an array containing only [1, 2] and $i is actually the size of this array. Then I'm computing the next line until I reach the one with the right number of participants.
On a side note: $i <<= 1 does the same than $i *= 2. You can read documentation about bitwise operators for further explanations.
About strong athletes, as you want to keep as much randomness as possible, here is a solution (probably not optimal but that's what I first thought):
Make two arrays, one with strongs and one with weaks
If there are no strongs or a single one, just shuffle the whole array and go to 8.
If there are more strongs than weaks (dunno if it can happen in your case but better be safe than sorry), shuffle the strongs and put the last ones with weaks so both arrays are the same size
Otherwise, fill up the strongs with null elements so the array size is a power of 2 then shuffle it
Shuffle the weaks
Prepare as many groups as they are elements in the strongs array and put in each group one of the strongs (or none if you have a null element) and complete with as many weaks as needed
Shuffle each group
Return the participants, ordered the same way than previous function resulting array
And the corresponding code:
function splitStrongsAndWeaks($participants) {
$strongs = array();
$weaks = array();
foreach($participants as $participant) {
if($participant != null && $participant[1] == 1)
$strongs[] = $participant;
else
$weaks[] = $participant;
}
return array($strongs, $weaks);
}
function insertNullValues($elements, $totalNeeded)
{
$strongsNumber = count($elements);
if($strongsNumber == $totalNeeded)
return $elements;
if($strongsNumber == 1)
{
if(mt_rand(0, 1))
array_unshift($elements, null);
else
$elements[] = null;
return $elements;
}
if($strongsNumber & 1)
$half = ($strongsNumber >> 1) + mt_rand(0, 1);
else
$half = $strongsNumber >> 1;
return array_merge(insertNullValues(array_splice($elements, 0, $half), $totalNeeded >> 1), insertNullValues($elements, $totalNeeded >> 1));
}
function shuffleParticipants($participants, $totalNeeded) {
list($strongs, $weaks) = splitStrongsAndWeaks($participants);
// If there are only weaks or a single strong, just shuffle them
if(count($strongs) < 2) {
shuffle($participants);
$participants = insertNullValues($participants, $totalNeeded);
}
else {
shuffle($strongs);
// If there are more strongs, we need to put some with the weaks
if(count($strongs) > $totalNeeded / 2) {
list($strongs, $strongsToWeaks) = array_chunk($strongs, $totalNeeded / 2);
$weaks = array_merge($weaks, $strongToWeaks);
$neededGroups = $totalNeeded / 2;
}
// Else we need to make sure the number of groups will be a power of 2
else {
$neededGroups = 1 << ceil(log(count($strongs), 2));
if(count($strongs) < $neededGroups)
$strongs = insertNullValues($strongs, $neededGroups);
}
shuffle($weaks);
// Computing needed non null values in each group
$neededByGroup = $totalNeeded / $neededGroups;
$neededNonNull = insertNullValues(array_fill(0, count($participants), 1), $totalNeeded);
$neededNonNull = array_chunk($neededNonNull, $neededByGroup);
$neededNonNull = array_map('array_sum', $neededNonNull);
// Creating groups, putting 0 or 1 strong in each
$participants = array();
foreach($strongs as $strong) {
$group = array();
if($strong != null)
$group[] = $strong;
$nonNull = array_shift($neededNonNull);
while(count($group) < $nonNull)
$group[] = array_shift($weaks);
while(count($group) < $neededByGroup)
$group[] = null;
// Shuffling again each group so you can get for instance 1 -> weak, 17 -> strong
shuffle($group);
$participants[] = $group;
}
// Flattening to get a 1-dimension array
$participants = call_user_func_array('array_merge', $participants);
}
// Returned array contains participants ordered the same way as getOrder()
// (eg. with 32 participants, first will have number 1, second number 17 and so on...)
return $participants;
}
If you want the resulting array to have as indexes the number in the bracket, you can simply do:
$order = getOrder(count($participants));
$participants = array_combine($order, shuffleParticipants($participants, count($order)));
Okay, I finally managed to convert my Tcl code to PHP! I changed some things too:
<?php
// Function generating order participants will be placed in array
function getBracket($L) {
// List will hold insert sequence
$list = array();
// Bracket will hold final order of participants
$bracket = array();
// The algorithm to generate the insert sequence
for ($n = 1; $n <= $L; $n += 1) {
// If 'perfect' number, just put it (Perfect no.s: 2, 4, 8, 16, 32, etc)
if (substr(log($n)/log(2), -2) == ".0") {
$list[] = $n;
// If odd number, stuff...
} elseif ($n % 2 == 1) {
$list[] = $list[($n-1)/2];
// Else even number, stuff...
} else {
$list[] = $list[$n/2-1]+$n/2;
}
}
// Insert participant order as per insert sequence
for ($i = 1; $i <= sizeof($list); $i += 1) {
$id = $i-1;
array_splice($bracket, $list[$id], 0, $i);
}
return $bracket;
}
// Find number of participants over 'perfect' number if any
function cleanList($L) {
for ($d = 1; $L > $d; $d += 1) {
$sq = $L-pow(2,$d);
if($sq == 0) {break;}
if($sq < 0) {
$d = pow(2,$d-1);
$diff = $L-$d;
break;
}
}
return $diff;
}
$participants = array(
array(0, "John", 2),
array(1, "Gagan", 1),
array(2, "Mike Tyson", 1),
array(3, "Gair", 1),
array(4, "Gale", 0),
array(5, "Roy Johnes", 0),
array(6, "Galip", 0),
array(7, "Gallagher", 0),
array(8, "Garett", 0),
array(9, "Nikolai Valuev", 0),
array(10, "Garner", 1),
array(11, "Gary", 0),
array(12, "Gelar", 0),
array(13, "Gershom", 1),
array(14, "Gilby", 0),
array(15, "Gilford", 1),
array(16, "Arianna", 0)
);
// Extract strength of participant
foreach ($participants as $array) {
$finorder[] = $array[2];
}
// Sort by strength, strongest first
array_multisort($finorder,SORT_DESC,$participants);
$order = array();
$outside = array();
// Remove participants above 'perfect' number
$remove = cleanList(sizeof($participants));
for ($r = 1; $r <= $remove; $r += 1) {
$removed = array_shift($participants);
$outside[] = $removed;
}
// Get corresponding bracket
$res = getBracket(sizeof($participants));
foreach ($res as $n) {
$order[] = $n;
}
// Align bracket results with participant list
array_multisort($order, $participants);
$participants = array_combine($res, $participants);
echo "The final arrangement of participants\n";
print_r($participants);
print_r($outside);
?>
Codepad demo
To get the logic for the order of insertion of elements, I used this pattern.
Also, since I'm not too familiar with PHP, there might be ways to make some things shorter, but oh well, as long as it works ^^
EDIT: Fixed an issue with first participant sorting and added new ticket numbers. For results without old ticket numbers, see here.
EDIT2: Managed to move keys into arrays; see here.
EDIT3: I thought that 'extra' participants should go outside the bracket. If you want null instead in the bracket, you can use this.
EDIT4: Somehow, PHP versions on codepad broke some stuff... fixing it below and removing initial index...:
<?php
// Function generating order participants will be placed in array
function getBracket($L) {
// List will hold insert sequence
$list = array();
// Bracket will hold final order of participants
$bracket = array();
// The algorithm to generate the insert sequence
for ($n = 1; $n <= $L; $n += 1) {
// If 'perfect' number, just put it (Perfect no.s: 2, 4, 8, 16, 32, etc)
if (int(log($n)/log(2)) || $n == 1) {
$list[] = $n;
// If odd number, stuff...
} elseif ($n % 2 == 1) {
$list[] = $list[($n-1)/2];
// Else even number, stuff...
} else {
$list[] = $list[$n/2-1]+$n/2;
}
}
// Insert participant order as per insert sequence
for ($i = 1; $i <= sizeof($list); $i += 1) {
$id = $list[$i-1]-1;
array_splice($bracket, $id, 0, $i);
}
return $bracket;
}
// Find number of participants over 'perfect' number if any
function cleanList($L) {
for ($d = 1; $L > $d; $d += 1) {
$diff = $L-pow(2,$d);
if($diff == 0) {break;}
if($diff < 0) {
$diff = pow(2,$d)-$L;
break;
}
}
return $diff;
}
$participants = array(
array("John", 2),
array("Gagan", 1),
array("Mike Tyson", 1),
array("Gair", 1),
array("Gale", 0),
array("Roy Johnes", 0),
array("Galip", 0),
array("Gallagher", 0),
array("Garett", 0),
array("Nikolai Valuev", 0),
array("Garner", 1),
);
// Extract strength of participant
foreach ($participants as $array) {
$finorder[] = $array[2];
}
// Sort by strength, strongest first
array_multisort($finorder,SORT_DESC,$participants);
$order = array();
// Add participants until 'perfect' number
$add = cleanList(sizeof($participants));
for ($r = 1; $r <= $add; $r += 1) {
$participants[] = null;
}
// Get corresponding bracket
$res = getBracket(sizeof($participants));
// Align bracket results with participant list
foreach ($res as $n) {
$order[] = $n;
}
array_multisort($order, $participants);
$participants = array_combine($res, $participants);
echo "The final arrangement of participants\n";
print_r($participants);
?>
ideone
viper-7
This sketchy code might be what you want:
<?php
class Pair
{
public $a;
public $b;
function __construct($a, $b) {
if(($a & 1) != ($b & 1))
throw new Exception('Invalid Pair');
$this->a = $a;
$this->b = $b;
}
}
class Competition
{
public $odd_group = array();
public $even_group = array();
function __construct($order) {
$n = 1 << $order;
$odd = array();
$even = array();
for($i = 0; $i < $n; $i += 4) {
$odd[] = $i + 1;
$odd[] = $i + 3;
$even[] = $i + 2;
$even[] = $i + 4;
}
shuffle($odd);
shuffle($even);
for($i = 0; $i < count($odd); $i += 2) {
$this->odd_group[] = new Pair($odd[$i], $odd[$i+1]);
$this->even_group[] = new Pair($even[$i], $even[$i+1]);
}
echo "Odd\n";
for($i = 0; $i < count($this->odd_group); ++$i) {
$pair = $this->odd_group[$i];
echo "{$pair->a} vs. {$pair->b}\n";
}
echo "Even\n";
for($i = 0; $i < count($this->even_group); ++$i) {
$pair = $this->even_group[$i];
echo "{$pair->a} vs. {$pair->b}\n";
}
}
}
new Competition(5);
?>

Categories