Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

vaticide's scratchpad

by vaticide (Scribe)
on Jun 24, 2005 at 21:52 UTC ( [id://469839]=scratchpad: print w/replies, xml ) Need Help??

#!/usr/local/perl5.8/bin/perl -w use strict; use Data::Dumper; my %balls; # at the start they might all be heavy or light my @might_be_heavy; my @might_be_light; # and we don't know if any of them are normal my @normal_balls; for (0..9) { %balls = initialize_balls(); # at the start they might all be heavy or light @might_be_heavy = keys %balls; @might_be_light = keys %balls; # and we don't know if any of them are normal @normal_balls = (); #map {print "$_ -> $balls{$_}\n"} keys %balls; my $oddball; my $weighing = 0; while (1) { last if ($oddball = pick_a_winner(\@normal_balls)); $weighing++; #print "Starting round $weighing\n"; my ($leftside, $rightside, $unused) = pick_balls(\@might_be_he +avy, \@might_be_light, \@normal_balls); check_ball_heft($leftside, $rightside, $unused); #print Dumper(\@might_be_heavy); #print Dumper(\@might_be_light); #print Dumper(\@normal_balls); } print "Ball $oddball is the odd ball. Took $weighing weighings.\n +"; } # subs sub initialize_balls { my %balls = map {$_, 1} 1..12; my $num = int( rand 12 ) + 1; my $adj = .1 * (int( rand 2 ) ? 1 : -1); $balls{$num} += $adj; return %balls; } sub check_ball_heft { my ($left, $right, $unused) = @_; die "Both sides must have the same number of balls." unless (scala +r keys %{$left} == scalar keys %{$right}); if (heft([values %{$left}]) > heft([values %{$right}])) { #print "Left is heavier.\n"; record_results([keys %{$left}], [keys %{$right}]); i_am_normal([keys %{$unused}]); } elsif (heft([values %{$left}]) < heft([values %{$right}])) { #print "Right is heavier.\n"; record_results([keys %{$right}], [keys %{$left}]); i_am_normal([keys %{$unused}]); } else { #print "They are the same.\n"; i_am_normal([keys %{$left}, keys %{$right}]); } } sub record_results { my ($heavy_balls, $light_balls) = @_; # remove lighter side balls from @might_be_heavy # and heavier side balls from @might_be_light foreach my $heavy_ball (@{$heavy_balls}) { @might_be_light = grep {$_ != $heavy_ball} @might_be_light; } foreach my $light_ball (@{$light_balls}) { @might_be_heavy = grep {$_ != $light_ball} @might_be_heavy; } } sub i_am_normal { my ($normal_balls) = @_; # add all these balls to @normal_balls and remove them from heavy +or light foreach my $normal_ball (@{$normal_balls}) { unshift @normal_balls, $normal_ball unless (grep {$_ == $norma +l_ball} @normal_balls); @might_be_heavy = grep {$_ != $normal_ball} @might_be_heavy; @might_be_light = grep {$_ != $normal_ball} @might_be_light; } } sub heft { my ($balls) = @_; my $heft = 0; foreach my $ball (@{$balls}) { $heft += $ball; } return $heft; } sub pick_balls { my ($maybe_heavy, $maybe_light, $normal) = @_; my $left; my $right; my %unused = %balls; # randomly my $balls_to_weigh = int(rand 5) + 1; for (1..$balls_to_weigh) { my $left_ball = (keys %unused)[int(rand(scalar keys %unused)-1 +) + 1]; $left->{$left_ball} = $unused{$left_ball}; delete $unused{$left_ball}; my $right_ball = (keys %unused)[int(rand(scalar keys %unused)- +1) + 1]; $right->{$right_ball} = $unused{$right_ball}; delete $unused{$right_ball}; } return $left, $right, \%unused; } sub pick_a_winner { my ($normal) = @_; # if there are 11 normal balls, we know which is the oddball. if (scalar @{$normal} == 11) { my $oddball; for my $starting_ball (1..12) { $oddball = $starting_ball unless grep {$_ == $starting_bal +l} @{$normal}; } return $oddball; } return; }
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

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

    No recent polls found