Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Lotto checker...

by fishy (Friar)
on Apr 15, 2014 at 14:41 UTC ( [id://1082350]=perlmeditation: print w/replies, xml ) Need Help??

or nice map/grep exercise...
#!/usr/bin/perl use strict; use warnings; my $draw = [ qw( 13 15 18 22 41 48 ) ]; my $bets = [ [ qw( 09 13 18 33 39 42 ) ], [ qw( 02 18 32 36 39 42 ) ], [ qw( 05 12 21 22 28 42 ) ], [ qw( 03 14 18 33 34 36 ) ], [ qw( 15 22 26 41 38 48 ) ], [ qw( 06 14 24 26 42 48 ) ], [ qw( 10 28 30 35 36 43 ) ], [ qw( 03 05 08 14 16 35 ) ], [ qw( 08 18 21 35 46 47 ) ], [ qw( 03 15 22 25 46 48 ) ], [ qw( 01 11 38 44 45 49 ) ], [ qw( 14 23 38 39 48 49 ) ], [ qw( 07 17 21 32 45 48 ) ], [ qw( 07 36 37 39 40 41 ) ], [ qw( 07 12 20 29 36 43 ) ] ]; map { my $bet = $_; my $hits = 0; map { my $one = $_; $hits += grep { $one eq $_ } @$bet; } @$draw; print join $", @$bet, "-->", $hits, $hits > 2 ? "*" : "", "\n"; } @$bets;

Replies are listed 'Best First'.
Re: Lotto checker...
by Arunbear (Prior) on Apr 15, 2014 at 15:26 UTC
    Why are $bets and $draw references rather than just arrays?

    Using map for side effects isn't as clear/obvious as using foreach.

Re: Lotto checker...
by bigj (Monk) on Apr 15, 2014 at 16:30 UTC
    If you change $draw into a hash, let's say to
    my %draw = (map {$_ => 1} qw/ ... /);
    you could count your hits easier with
    ... my $hits = @draw{@$bet}; ...
    In addition, as already said, use for or foreach if you want to loop an array and map if you want to create a new list. And IMHO, don't use unnecessary refs if direct arrays or hashs will do it also. It just makes the code harder to read and to maintain.

    Greetings,
    Janek

      my %draw = (map {$_ => 1} qw/ ... /);

      This is a good idea. [Minor point: the parentheses aren't necessary.]

      my $hits = @draw{@$bet};

      This is a less good idea: it isn't doing what you appear to think it does. See the following (and the examples that follow it) in "perldata: Slices":

      "Slices in scalar context return the last item of the slice."

      So, $hits will only ever equal 1 or undef, and the occasional correct output (e.g. "06 14 24 26 42 48 --> 1") will be just coincidence.

      Update: Just it case it isn't clear: in list context, @draw{@$bet} will always contain six elements, each of which will be either 1 or undef.

      -- Ken

Re: Lotto checker...
by kcott (Archbishop) on Apr 15, 2014 at 20:43 UTC

    G'day fishy,

    Applying this advice from Arunbear and bigj:

    my %draw = map { $_ => 1 } qw( ... ); my @bets = ( ... );

    You can reduce your original code, which is somewhat difficult to read and maintain, to just this:

    print for map { my $hits = grep { $draw{$_} } @$_; "@$_ --> $hits" . ($hits > 2 && ' *') } @bets;

    My test code and results are in the spoiler:

    -- Ken

      Venerable answers.
      Flexing my mind and stretching my Perl.

      Many Thanks, Monks!

      P.D.
      kcott: just concat "\n" at print argument
        "kcott: just concat "\n" at print argument"

        No. There's no need to do that.

        Look at the full code and output I posted in the spoiler. Note that the output doesn't require additional newlines. Did you run it? Did you get a different result?

        See the first line of that code:

        #!/usr/bin/env perl -l

        Look at "perlrun: Command Switches" to see what the '-l' switch does.

        -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1082350]
Approved by Athanasius
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2024-04-20 03:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found