I want to make sure i understand what you're trying to do. So, by your example, the numbers in List dont need to be unique. By #3, the 2 numbers need to be unique in the pairs you want.
There is nothing in your conditions that says the same pair cannot appear more than once, just not in the same row. But, your code prohibits that case, with the line
next if defined $hash->{$x}{$y};
The code in your post is only generating pairs, not rows.
Also, each element in the List is only used in 1 pair.
If my understanding is correct, your get_pairs() function only gets 1 of many, many possible pair sets. Also, since you started with 36 elements in the array, and only 16 pairs were returned, there are still 4 elements in the array that werent assigned to pairs.
Ok, if thats correct, with you fixing P=2, there should be 4 numbers in each row (2 pairs of 2 numbers). In general, there are 2*P numbers in each row.
It may be easier to just try to create rows of 2P=4 unique numbers. Then, there are
( C(4,2)*C(2,2) ) / 2
legal pairings for each row, since all numbers in each row are unique. (this is, of course if you allow the same pair in 2 different rows. If not, there are fewer pairings available.
BTW, C(X,Y) means the number of combinations of X things taken Y at a time.
UpdateThe formula was wrong for the number of possible pairings that can be picked from a row of unique numbers. I forgot that (a,b)(c,d) and (c,d)(a,b) were both being counted, so i added the
/2