You did not specify, so I assume that each letter in the input can be used only once.
[Since the specified letters in the input can be used several times, but I'm going to leave this post here if someone finds it useful.]
The key to doing this effectively is sorting letters in words.
abracadabra => AAAAABBCDRR abroad => AABDOR drab => ABDR
Then it becomes clear that "gray" is in "gibberish".
abracadabra => AAAAABBCDRR drab => AB DR
And that "abroad" is not.
abracadabra => AAAAABBCD RR abroad => AA B DOR
Call the sorted letter "signature". The word "B" in is in the word "A" if you can remove the letters from the signature "A" to get the signature "B". This is easy to verify with the regex pattern.
sig('drab') =~ /^A?A?A?A?A?B?B?C?D?R?R?\z/
Or, if we eliminate unnecessary rollback for efficiency, we get
sig('drab') =~ /^A?+A?+A?+A?+A?+B?+B?+C?+D?+R?+R?+\z/
Now that we know which template we want, it's just a matter of building it.
use strict; use warnings; use feature qw( say ); sub sig { join '', sort grep /^\pL\z/, split //, uc $_[0] } my $key = shift(@ARGV); my $pat = sig($key); $pat =~ s/.\K/?+/sg; my $re = qr/^(?:$pat)\z/s; my $shortest = 9**9**9; my $longest = 0; my $count = 0; while (my $word = <>) { chomp($word); next if !length($word);
Example:
$ perl script.pl EBLAIDL /usr/share/dict/words A Abe Abel Al ... libel lid lie lied Words: 117 Shortest: 1 Longest: 6