[Purdue-pm] fast table lookup of randomly associated items
Mark Senn
mark at ecn.purdue.edu
Sat May 22 22:19:20 PDT 2010
I like this solution because it best echos the problem statement.
The __DATA__ section can be moved to a separate file if wanted.
-mark
#!/usr/bin/perl
use Modern::Perl;
my @table;
while (<DATA>)
{
chomp;
my ($range, $letter) = split /\s+/;
($range =~ /-/) or $range .= "-$range";
my ($min, $max) = split /-/, $range;
@table[$min..$max] = ($letter) x ($max-$min+1);
}
my $number = int 1 + rand $#table;
say "number $number is associated with $table[$number]";
__DATA__
1-5 A
6 B
7-12 C
13-20 D
21-25 E
26-30 F
> Say I have a table like the following:
>
> number Item
> 1-5 A
> 6 B
> 7-12 C
> 13-20 D
> 21-25 E
> 26-30 F
>
> Say I then have a random number generator that spits out a number
> from 1-30.
>
> What is the fastest way to look up the item associated with that random
> number?
>
> For more fun, say I want to store that table in a text file what is a
> good way to represent that?
>
> I kicked around some ideas and the easiest solution I could come up with
> is the following. I settled on JSON since it's a bit more portable than
> most and I like its syntax better than YAML.
> ===================================
>
> #!/usr/local/bin/perl
>
> use 5.010;
>
> use strict;
> use warnings;
>
> use File::Slurp;
> use JSON;
>
> my $table = q(table.json);
> my $json_text = read_file( $table ) ;
> my $data = from_json($json_text);
>
> my $number = int(rand(30)+1);
> my $item = q(nothing);
> foreach my $row ( @$data ) {
> if ( $number > $row->[0] ){
> }
> else {
> $item = $row->[1];
> last;
> }
> }
>
> say qq($number associated with $item);
>
> exit(0);
>
> ===================================
> table.json:
>
> [
> [5,"A"],
> [6,"B"],
> [12,"C"],
> [20,"D"],
> [25,"E"],
> [30,"F"]
> ]
And in a later message Joe wrote:
> Maybe fastest might be misnomer. I was hoping I could do something like:
>
> my $random
> my ($key) = grep { $_ ~~ $random } keys %table;
>
> I stumbled across something like this at stackoverflow but I can't find
> it now.
>
> I was thinking that I could make the hash keys the range and then use
> smart matching to figure out which key the random number is in the range of.
>
> Using ranges for hash keys does weird things however. Let alone that
> they don't get treated as a range in the smart match.
>
> Well, to be honest I couldn't really get the ranges as keys thing
> working so I don't know if it would really treat the key as a range.
>
> Maybe clever is what I'm looking for. :-)
>
> >> For more fun, say I want to store that table in a text file what is a
> >> good way to represent that?
> >
> > I sort of liked your human readable format above. JSON is fine but
> > not as clear to the lay person.
>
> I was using YAML for awhile but about 6 months or so ago I switched to
> JSON. It's easier for me to understand than YAML (which has some white
> space being important stuff that annoys me) is easily portable between
> langues (especially javascript since it is really just javascript).
More information about the Purdue-pm
mailing list