If you can come up with a better title after reading the question, please feel free to change it.
So, as input I have an integer, which is an even number between 2 and 20. Let's call this integer $teams
. What I need to do is generate a $teams x $teams
sized matrix of numbers between 1 and $teams-1
(inclusive) while respecting the following rules:
- The diagonal (from top left to bottom right) has value -1.
- The same number may not appear in the same column or row more than once.
- If a number appears in column N, then in may not appear in row N. For example, if it appears in column #2, it may not appear in row #2, etc.
Note that we're only looking at the part above the diagonal. The part below it is just a reflection of that (each number is its reflection + $teams - 1), and it doesn't matter for this problem.
The first 2 conditions were fairly easy to accomplish, but the 3rd one is killing me. I don't know how to make it happen, especially since the $teams
number could be any even number between 2 and 20. The code that gives a correct output for conditions 1 and 2 is given below. Can someone help me with condition number 3?
$teams = 6; //example value - should work for any even Int between 2 and 20
$games = array(); //2D array tracking which week teams will be playing
//do the work
for( $i=1; $i<=$teams; $i++ ) {
$games[$i] = array();
for( $j=1; $j<=$teams; $j++ ) {
$games[$i][$j] = getWeek($i, $j, $teams);
}
}
//show output
echo '<pre>';
$max=0;
foreach($games as $key => $row) {
foreach($row as $k => $col) {
printf('%4d', is_null($col) ? -2 : $col);
if($col > $max){
$max=$col;
}
}
echo "\n";
}
printf("%d teams in %d weeks, %.2f weeks per team\n", $teams, $max, $max/$teams);
echo '</pre>';
function getWeek($home, $away, $num_teams) {
if($home == $away){
return -1;
}
$week = $home+$away-2;
if($week >= $num_teams){
$week = $week-$num_teams+1;
}
if($home>$away){
$week += $num_teams-1;
}
return $week;
}
The current code (for $teams=6) gives the following output:
-1 1 2 3 4 5
6 -1 3 4 5 1
7 8 -1 5 1 2
8 9 10 -1 2 3
9 10 6 7 -1 4
10 6 7 8 9 -1
6 teams in 10 weeks, 1.67 weeks per team
As you see, the number 1 appears both in the 2nd column and 2nd row, number 4 appears both in the 5th column and 5th row etc, which breaks rule #3.
nth collumn
of the first row. Well, you know that in the first row you have the numbers from-1
ton-1
. When you generate the numbers for row numberx
you can easily skip the number which is in$games[1][x]
. Hope that helps somewhat ;-) – Havelock