Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Re^4: Golf: Improve this guy's fail . . . please!

by zhespelt (Sexton)
on Jul 16, 2009 at 15:02 UTC ( #780742=note: print w/replies, xml ) Need Help??

in reply to Re^3: Golf: Improve this guy's fail . . . please!
in thread Golf: Improve this guy's fail . . . please!

I know it's not as elegant as the code above, but I think it's a bit better than my first one.
#!/usr/bin/perl -w use strict; use warnings; local $/ = undef; my $string = <>; my @array = split(//, $string); my %hash; foreach (@array) { if ($_ =~ /\w/) { $hash{$_}++; } } my @keys = sort keys %hash; my $total; foreach (values %hash) { $total += $_; } foreach (@keys) { printf "%s\t%d\t%.3f\n", $_, $hash{$_}, $hash{$_}/$total; } print "$total characters\n";

Replies are listed 'Best First'.
Re^5: Golf: Improve this guy's fail . . . please!
by grinder (Bishop) on Jul 17, 2009 at 10:54 UTC

    This is lovely code. It has a nice balance between terseness and clarity.

    Despite your baptism of fire, I hope you stay around. You'll learn a lot of stuff, not all necessarily about Perl.

    • another intruder with the mooring in the heart of the Perl

Re^5: Golf: Improve this guy's fail . . . please!
by Boldra (Deacon) on Jul 23, 2009 at 09:34 UTC
    This code is a huge improvement, except for the variable names!

    You started with names like $total_chars and %ascii_counts, and ended up with $total and %hash. %hash and @array are about the worst variable names you can use.

    You've come a long way very quickly, and kudos for taking the criticism well.

    - Boldra
Re^5: Golf: Improve this guy's fail . . . please!
by dragonchild (Archbishop) on Jul 29, 2009 at 02:42 UTC
    I was hoping you'd come by. Welcome to the Monastery.

    This is 100x better. Well-done. Variable names can be improved, but I can actually scan this code and understand the basic intent. The biggest improvement now would be to skip intermediate variables that only exist once. So, something like:

    use strict; use warnings FATAL => 'all'; use List::Utils qw( sum ); my $input = do { local $/; <>; }; my %letters; $letters{$_}++ for grep /\w/, split //, $input; my $total = sum values %letters; for ( sort keys %letters ) { printf "%s\t%d\t%.3f\n", $_, $letters{$_}, $letters{$_}/$total; } print "$total characters\n";
    The big differences there are:
    • Removing intermediate variables
    • Scoping the localization of $/
    • Using a module to do the summation
    • Chaining functions in the grep split.
    This would be considered more "perlish". Remember - readablity also includes conciseness. This is why well-written Java is less readable than well-written Perl.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      my %letters;
      $letters{$_}++ for grep /\w/, split //, $input;

      That would be simpler as:

      my %letters;
      $letters{$_}++ for $input =~ /\w/g;

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://780742]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2018-01-22 00:37 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (230 votes). Check out past polls.