Here's a first pass at it.
It does partial math (same number of digits on both sides) to
cut off further consideration because of duplicates or 0.
It does base 18 in under 3 minutes.
#!/usr/bin/perl -l
# https://perlmonks.org/?node_id=1218964
use strict;
use warnings;
use POSIX;
my $base = shift // 10;
my @numbers = (0..9, 'a'..'z')[0..$base-1];
my $numberlength = $base - 1 >> 1;
my $pattern = '-' x $numberlength . '=' . '-' x $numberlength . '*';
sub inbase
{
my ($n, $b) = @_;
my $ans = '';
while($n > 0)
{
$ans = $numbers[$n % $b] . $ans;
$n = int $n / $base;
}
$ans || 0;
}
# dddd=dddd*d # for base 10
my $solutions = my $count = 0;
my @queue = map "$pattern$_", @numbers[2..$#numbers];
while( @queue )
{
$count++;
$_ = shift @queue;
/(\w).*\1/ and next;
if( !/.*=.*\K-/ )
{
print;
$solutions++;
next;
}
my ($before, $after) = ($`, $');
my $mul = POSIX::strtol( substr( $after, -1 ), $base );
for my $d ( @numbers[1..$#numbers] )
{
$_ =~ $d and next;
my $new = "$before$d$after";
$new =~ /=-*(\w+)/ or next;;
my $len = length $1;
my $prod = POSIX::strtol( $1, $base ) * $mul;
my $baseprod = inbase( $prod, $base );
length $baseprod > $numberlength and next;
substr $new, $numberlength - $len, $len, substr $baseprod, -$len;
$new =~ /0|(\w).*\1/ and next;
push @queue, $new;
}
}
print "\nsteps $count solutions $solutions";