Lingua::Pangram

Smylers Belfast-PM at stripey.com
Thu Jan 24 13:35:24 CST 2002


I don't get this mail at work, so I only started golfing yesterday after
everybody else had finished.  I didn't get anything spectacularly short,
but the trouble is I don't understand why my attempt works!  Here it is
(with what I believe was the shortest working entry for comparison):

  perl -ne'@$_{/[a-z]/gi}=1;%$_>25&&print'  # 40
  perl -pe'for$i(a..z){/$i/i or$_=""}'      # 36

It relies on the hashing sticking each letter of the alphabet in a
separate bucket but upper- and lower-case versions of the same letter in
the same bucket.  This seems to work on 5.005_03; I haven't test it on
anything else.

But why does it still print the right thing at the end?  This version
works as expected:

  perl -ne'my%k;@k{/[a-z]/gi}=1;%k>25&&print'  # 43

The my is needed to empty %k for each line (otherwise once a pangram is
found, all subsequent lines are printed).  I thought of using $_ as a
pointer to the hash, since Perl is overwriting $_ each time through the
loop anyway, so this works:

  perl -ne'$m=$_;@$_{/[a-z]/gi}=1;%$_>25&&print$m'  # 48

$_ gets set to the current line, I preserve that in $m and use %$_ as
the hash, printing out $m if appropriate.  Except that $m isn't needed
-- just printing $_ works.  Despite being used in the middle of the line
as a hash reference, it still has the text of the line in it, which I
don't understand at all.

In fact, in this:

  perl -nle'@$_{/[a-z]/gi}=1;%$_>25&&print"$_:".%$_'

it's even possible to have Perl use $_ as a string, then me use it as a
hash ref, then print the string, and then print the hash ref!  Surely $_
should print "HASH(0x80d43dc)" or something?

De-referencing $_ and re-referencing it again does print that:

  perl -nle'@$_{/[a-z]/gi}=1;%$_>25&&print"$_:".%$_.":".\%$_'

Please can somebody explain what I'm missing here?

Unrelated to that, somebody (sorry, I just expunged my inbox then
realized I shouldn't've done cos I can't remember who) commented on all
the solutions using regexps.  Here's the shortest I came up with which
doesn't:

  perl -naF\| -e'@$_{a..z}=1;delete@$_{map{lc}@F};%$_||print'  # 59

Cheers.

Smylers




More information about the Belfast-pm mailing list