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

Re: $str to %hash to @ary

by QM (Parson)
on Jul 22, 2004 at 21:27 UTC ( [id://376725]=note: print w/replies, xml ) Need Help??


in reply to $str to %hash to @ary

At the expense of making the lookup a little slower:
my $str="17:43:33:21:23:19:27:6"; my %hash=split/:/,$str; my $count; my %ad_lookup; foreach my $k(keys %hash) { $count += $hash{$k}; $ad_lookup{$count} = $k; } my $rand = rand(100); my $adid; foreach ( sort {$a <=> $b} keys %ad_lookup ) { $adid = $ad_lookup{$_} unless defined( $adid); if ( $_ <= $rand ) { $adid = $ad_lookup{$_}; } else { last; } }
Of course, if you want the lookup to be faster, use a binary search instead.

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re^2: $str to %hash to @ary
by fizbin (Chaplain) on Jul 24, 2004 at 14:20 UTC
    Unfortunately, your code doesn't actually work; as written it lumps the last two outputs together, and I see it outputting "6" 60% of the time, and "19" never.

    I'll go post my test code elsewhere and you can see if I've somehow miscopied your code.

    -- @/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/
      You're correct. I didn't test the code well, and seem to have gotten several things backward or out of whack. Here's properly tested code (I hope):
      #!/your/perl/here use strict; use warnings; my $str="17:43:33:21:23:19:27:6"; my %hash=split/:/,$str; my $count; my %ad_lookup; foreach my $k(keys %hash) { $count += $k; $ad_lookup{$count} = $hash{$k}; } my @ad_lookup_sorted_keys = sort {$b <=> $a} keys %ad_lookup; my %seen; for my $rand ( 1..$count ) { # my $rand = rand($count); my $adid; foreach my $key ( @ad_lookup_sorted_keys ) { if ( $rand <= $key ) { $adid = $ad_lookup{$key}; } else { last; } } # print "$adid\n"; $seen{$adid}++; } foreach my $k ( sort {$a <=> $b} keys %seen ) { print "\$seen{$k}: $seen{$k}\n"; }
      Which outputs:
      $seen{6}: 27 $seen{19}: 23 $seen{21}: 33 $seen{43}: 17
      [There would be a slight shift going back to rand, because of the 0..99 and 1..100 difference. I believe you just need to change:
      $ad_lookup{$count} = $hash{$k};
      to:
      $ad_lookup{$count-1} = $hash{$k};
      ]

      I should note there are several ways to do this and get it right, and this is but one. Also, the key sort is only done once. A binary search on the keyspace would be faster, if there are many keys, but I'd estimate you would need a hundred keys or so to make it worth while. [Feel free to test that if you like]

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-04-19 20:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found