If solution is thought of as symmetric matrix with all-unique elements (i.e. "edge labels") per row (and therefore, per column) and crossed-out dummy diagonal, then quite formal algorithm to build it could be as follows. Code is not pretty, at least I hope I streamlined it enough after couple of, even uglier, attempts.
use strict;
use warnings;
use feature 'say';
use constant LETTERS => join '', 'A'..'Z', 'a'..'z'; # template
use constant N => 51; # number of "e
+dges"
die if not N % 2 # (1) prohibit odd nodes number
or N > 51; # (2) "template" limitation
say '_' . substr LETTERS, 0, N;
my $last = substr LETTERS, N - 1, 1; # "collect" last line here
for ( 1 .. N - 1 ) {
my $s = substr LETTERS, 0, N;
my $sfx = substr $s, 0, $_ - 1, '';
$s .= $sfx; # rotate left
$sfx = substr $s, $_, 1, '_';
$s .= $sfx; # ...& append replaced diagona
+l item
say $s;
$last .= substr $s, -1;
}
say $last . '_';
__END__
Extended 2:53 2/20/22: now here's formal generation code for both odd/even number of "edges", at expense of introducing additional "edge label" (a star) in latter case:
use strict;
use warnings;
use feature 'say';
use constant LETTERS => join '', 'A'..'Z', 'a'..'z';
use constant N => 12;
say '_' . substr LETTERS, 0, N;
my $last = substr LETTERS, N - 1, 1;
for ( 1 .. N - 1 ) {
my $s = substr LETTERS, 0, N;
my $sfx = substr $s, 0, $_ - 1, '';
$s .= '*' unless N % 2;
$s .= $sfx;
$sfx = substr $s, $_, 1, '_';
$s .= $sfx if N % 2;
say $s;
$last .= substr $s, -1;
}
say $last . '_';
__END__
_ABCDEFGHIJKL
A_CDEFGHIJKL*
BC_EFGHIJKL*A
CDE_GHIJKL*AB
DEFG_IJKL*ABC
EFGHI_KL*ABCD
FGHIJK_*ABCDE
GHIJKL*_BCDEF
HIJKL*AB_DEFG
IJKL*ABCD_FGH
JKL*ABCDEF_HI
KL*ABCDEFGH_J
L*ABCDEFGHIJ_