Create multiple random pairwise combination of words [closed]

File 1 contains the list of words that needed to be randomly paired

Tiger
Cat
Fish
Frog
Dog
Mouse
Elephant
Monkey

File 2 contains the pairs that should not be used (in any solution) during random pairing.

Elephant-Dog
Cat-Fish
Monkey-Frog

Dog-Elephant, Fish-Cat, Frog-Monkey should also be deleted as their pair appeared in File2 (irrespective to direction) I need total of 6 solutions and in every solution, there should be maximum of 5 pairs. Tiger-Cat and Cat-Tiger should be treated as same and if they appear together in any solution one should be deleted. The same pair such as Frog-Dog can appear in many solutions.

The output looks like (here only one solution is given)

Tiger-Cat
Cat-Dog
Monkey-Cat
Frog-Dog
Elephant-Cat
• Is Cat-Cat permitted? – choroba Oct 10 at 7:48
• Nice task. What is your question? Did you encounter any problems on solving the task or what? – Philippos Oct 10 at 7:57
• no, such pairs are not permitted – Patel Oct 10 at 7:57

Perl solution.

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use List::Util qw{ shuffle };

open my \$fh_list, '<', shift or die \$!;
chomp( my @words = sort <\$fh_list> );

open my \$fh_ban, '<', shift or die \$!;
my %ban;
while (<\$fh_ban>) {
chomp;
my (\$ban1, \$ban2) = sort split /-/;
undef \$ban{"\$ban1-\$ban2"};
}

my @all;
for my \$i1 (0 .. \$#words) {
for my \$i2 (\$i1 + 1 .. \$#words) {
my \$pair = [ \$i1, \$i2 ];
push @all, \$pair unless exists \$ban{"\$words[\$i1]-\$words[\$i2]"};
}
}

my @solutions;
my %used;
while (@solutions < 6) {
my \$solution = join ' ', sort +(shuffle(0 .. \$#all))[0 .. 4];
redo if exists \$used{\$solution};

undef \$used{\$solution};
push @solutions, [
map join('-', @words[
@{ \$all[\$_] }[int rand 2 ? (0, 1) : (1, 0)]
]), split ' ', \$solution
];
}

say join "\n", @\$_, '---' for @solutions;

It first reads the words into an array and the banned pairs into a hash. It then generates all the possible combinations where the first element sorts before the second one. It then shuffles the all possible pairs and selects the first five until it has 6 different solutions. The "@all" array contains just the indices of the elements, and they are randomly shuffled when outputting the corresponding elements, so you can get both "Cat-Dog" and "Dog-Cat".

Example output:

Elephant-Cat
Monkey-Cat
Fish-Elephant
Monkey-Fish
Frog-Tiger
---
Tiger-Cat
Tiger-Fish
Fish-Elephant
Dog-Monkey
Cat-Frog
---
Tiger-Fish
Cat-Elephant
Elephant-Frog
Mouse-Elephant
Frog-Cat
---
Tiger-Fish
Mouse-Fish
Monkey-Fish
Frog-Tiger
Cat-Dog
---
Dog-Frog
Elephant-Frog
Dog-Tiger
Tiger-Mouse
Tiger-Monkey
---
Tiger-Cat
Elephant-Frog
Tiger-Mouse
Cat-Frog
Cat-Dog
---

bash solution:

for i in {1..6}; do

printf '==== solution %d ====\n' "\$i"

# initialize solution
solution=()

while [ \${#solution[@]} -lt 5 ]; do
# select two random lines from file1
w1=\$(shuf -n 1 file1)
w2=\$(shuf -n 1 file1)

# skip if word1 is the same as word2
[ "\$w1" == "\$w2" ] && continue

# skip if pair exists in same solution or is not allowed from file2
cat <(printf '%s\n' "\${solution[@]}") file2 | grep -qx "\$w1-\$w2" && continue
cat <(printf '%s\n' "\${solution[@]}") file2 | grep -qx "\$w2-\$w1" && continue

# output
solution+=("\${w1}-\${w2}")
done
printf '%s\n' "\${solution[@]}"
done

Output:

==== solution 1 ====
Fish-Monkey
Elephant-Mouse
Dog-Tiger
Mouse-Fish
Dog-Cat
==== solution 2 ====
Cat-Frog
Elephant-Monkey
Cat-Mouse
Tiger-Elephant
Fish-Tiger
==== solution 3 ====
Cat-Frog
Tiger-Monkey
Frog-Elephant
Dog-Fish
Elephant-Cat
==== solution 4 ====
Cat-Dog
Mouse-Elephant
Monkey-Elephant
Cat-Monkey
Tiger-Cat
==== solution 5 ====
Tiger-Monkey
Tiger-Cat
Mouse-Monkey
Mouse-Fish
Monkey-Cat
==== solution 6 ====
Monkey-Mouse
Dog-Monkey
Monkey-Fish
Tiger-Elephant
Cat-Tiger