Have you considered Algorithm::Permute? It might be helpful, but I have not used it much myself. Just a thought.
| [reply] |
| [reply] |
merlyn has a nice writeup about permutations and combinations here. You may want to do a super search on permutations and combinations.
-- flounder | [reply] |
There's no need to calculate all the permutations or combinations.
Think people, think! You have 48 players, arrange them in a 6 x 8
matrix:
0 6 12 18 24 30 36 42
1 7 13 19 25 31 37 43
2 8 14 20 26 32 38 44
3 9 15 21 27 33 39 45
4 10 16 22 28 34 40 46
5 11 17 23 29 35 41 47
Then you can create teams by going around horizontally, vertically,
and diagonally. You just have to skip to a different column or row
whenever to cross an edge. Or, in other words, we're going to tile the
plane with the above matrix, but each time we put down another time,
we shift a bit. We shift a row if a place a tile to the right, and a
column if we place a tile above. We can then start any place and either
go to the right, go down, or go up-right and make a team from each of
the next 6 numbers; repeating that 8 times.
This boils down to the following program:
#!/usr/bin/perl
use strict;
use warnings 'all';
my @people = (0 .. 47);
my @data;
my @z = (0, 0, 0);
my @inc = (1, 6, 5);
my @skew = (0, 1, 0);
my @drift = (0, 0, 12);
for (my $x = 0; $x < 8; $x ++) {
for (my $y = 0; $y < 6; $y ++) {
for (my $z = 0; $z < @z; $z ++) {
push @{$data [$z] [$x]} => $people [$z [$z]];
$z [$z] += $inc [$z];
$z [$z] += $drift [$z] if 5 == $z [$z] % 6;
$z [$z] -= @people - $skew [$z] if $z [$z] >= @people;
}
}
}
my $r = 0;
foreach my $info (@data) {
printf "Round %d\n", ++ $r;
my $t = 0;
foreach my $team (@$info) {
printf "Team %d: ", ++ $t;
map {printf "%2d " => $_} @$team;
print "\n";
}
print "\n";
}
__END__
Round 1
Team 1: 0 1 2 3 4 5
Team 2: 6 7 8 9 10 11
Team 3: 12 13 14 15 16 17
Team 4: 18 19 20 21 22 23
Team 5: 24 25 26 27 28 29
Team 6: 30 31 32 33 34 35
Team 7: 36 37 38 39 40 41
Team 8: 42 43 44 45 46 47
Round 2
Team 1: 0 6 12 18 24 30
Team 2: 36 42 1 7 13 19
Team 3: 25 31 37 43 2 8
Team 4: 14 20 26 32 38 44
Team 5: 3 9 15 21 27 33
Team 6: 39 45 4 10 16 22
Team 7: 28 34 40 46 5 11
Team 8: 17 23 29 35 41 47
Round 3
Team 1: 0 17 22 27 32 37
Team 2: 42 11 16 21 26 31
Team 3: 36 5 10 15 20 25
Team 4: 30 47 4 9 14 19
Team 5: 24 41 46 3 8 13
Team 6: 18 35 40 45 2 7
Team 7: 12 29 34 39 44 1
Team 8: 6 23 28 33 38 43
Abigail
| [reply] [d/l] |
Some people asked me to give an example. The example I was give to work with was 48 people that needed to be divided up into 8 teams, which means 6 people per team. And then there needed to be 3 sets of these 8 teams, so that the people in the first set did not have the same people on their team in the second and third set.
| [reply] |
The first step would be to find the number of choices. In this case, we would use a combination rather than a permutation, since the order of our choices is irrelevant. We can find this number with:
sub choose {
my ($n, $k) = @_;
my ($result, $j) = (1, 1);
return 0 if $k > $n || $k < 0;
$k = ($n - $k) if ($n - $k) < $k;
while ( $j <= $k ) {
$result *= $n--;
$result /= $j++;
}
return $result;
}
my $people = 48;
my $teams = 8;
my $seasons = 3;
print choose($people, ($people/$teams));
In your case, there are a possible 12271512 different team combinations, but this isn't the complete answer yet. You'll actually want to generate these teams such that you can find which of them have repeated couples.
I've got some coding for work to do, but I'll crunch on this throughout the day and update as I can, barring someone else having more freetime and posting a solution before I do.
C-.
Update: Or you could completely ignore my intellectually overstimulated response and go with what Abigail-II suggested, which will actually solve the problem. Thanks for the instruction.
---
Flex the Geek | [reply] [d/l] |