in reply to Find the shortest word in the English Language with: a b c d e f

The empty diamond with @ARGV lets (edit: not "let's") you win a few chars:

open$:,"</usr/share/dict/words";while(<$:>){...} @ARGV="/usr/share/dict/words";while(<>){...}
Using the magic increment on a string (eg 'a'), you can have /$a/ search for the successive letters in the alphabet (also "push if" is shorter than "next unless; push"):
$a='a';$a++while/$a/;push@_,$_ if$a gt'f' next unless/(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)(?=.*f)/i;push@_,$_

And I thought the sorting was too verbose, so I stored the matching words by length to begin with:

@ARGV="/usr/share/dict/words";while(<>){$a='a';$a++while/$a/i;push@{$_ +[length]},$_ if$a gt'f'}@_=map{$_?@$_:()}@_ open$:,"</usr/share/dict/words";while(<$:>){next unless/(?=.*a)(?=.*b) +(?=.*c)(?=.*d)(?=.*e)(?=.*f)/i;push@_,$_}@_=sort{length$a<=>length$b} +@_
That's 31 fewer chars than your version, not counting the extra ' in your perl code ;-)

A chomp might be needed somewhere though, adding at least 5 chars.

Replies are listed 'Best First'.
Re^2: Find the shortest word in the English Language with: a b c d e f
by jwkrahn (Abbot) on Jul 04, 2018 at 18:51 UTC

      Yes, and I can remove three additional chars by using bareword a and f rather than strings:

      @ARGV="/usr/share/dict/words";while(<>){$a='a';$a++while/$a/i;push@{$_ +[length]},$_ if$a gt'f'}@_=map{$_?@$_:()}@_ @ARGV="/usr/share/dict/words";while(<>){$a=a;$a++while/$a/i;push@{$_[y +///c]},$_ if$a gt f}@_=map$_?@$_:(),@_

      And who needs a path when perl can just guess? :P. @ARGV=</*/*/*/words>;while(<>){$a=a;$a++while/$a/i;push@{$_[y///c]},$_ if$a gt f}@_=map$_?@$_:(),@_ Which brings the count to 100 chars (including the \n)

        I'm not accustomed to needing to specify the argument within the code. It's not like it's a command-line flag. I count yours at 78.

        while(<>){$a=a;$a++while/$a/i;push@{$_[y///c]},$_ if$a gt f}@_=map$_?@ +$_:(),@_

        If you're to actually print out the shortest, make it 89. Still quite a bit shorter than mine.

        while(<>){$a=a;$a++while/$a/i;push@{$_[y///c]},$_ if$a gt f}@_=map$_?@ +$_:(),@_;print$_[0]

        Of course, looking closely only one of your loops needs to be of the 'while' variety. 87 (or 76 unconcerned about output).

        for(<>){$a=a;$a++while/$a/i;push@{$_[y///c]},$_ if$a gt f}@_=map$_?@$_ +:(),@_;print$_[0]
        for(<>){$a=a;$a++while/$a/i;push@{$_[y///c]},$_ if$a gt f}@_=map$_?@$_ +:(),@_