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

Re: A script with a loop is running my computer Out of memory

by jethro (Monsignor)
on Feb 02, 2011 at 21:53 UTC ( [id://885862]=note: print w/replies, xml ) Need Help??


in reply to A script with a loop is running my computer Out of memory

First two off topic optimizations: If you used an array for %generations you wouldn't need to sort the keys (just store generation x into arrays slot x). Also max(keys %generations)==$generations.

Also you are summing up a lot of random values between 0 and 5 (distributed evenly). Basically the average number of offsprings per person you will get is 2.5, if you do this a lot. Change your last line to

printf "%${max_length_generation}s: %${max_length_children}s %s\n" +,$_,commify($generations{$_}),$generations{$_}/$generations{max($_-1, +1)};

to see this effect. It also shows how to calculate the next generation directly if you don't mind to get a clean statistical average instead of your calculated numbers

By the way, if you want to try to not have an evenly distributed number of offspring (i.e. families with two kids should be more common than with five, at least in our century), you might define an array with a different distribution:

my @distribution=(0,0,1,1,1,2,2,2,2,3,3,4,5);

and in your loop use the random number to get one random value out of the array:

my $children = $distribution[rand(@distribution)]; # instead of my $children = int(rand(6));

Replies are listed 'Best First'.
Re^2: A script with a loop is running my computer Out of memory
by Lady_Aleena (Priest) on Feb 04, 2011 at 14:09 UTC

    Thank you for the idea of distribution, I toyed with the idea while writing it, but thought int(rand(6)) was easier. You are right though, it should be weighted towards fewer children per person of the previous generation. However, I found a situation where I have had to stop the loop. In the first few iterations of the main loop, a generation could end up with 0 children in it. At that point, going any further would be pointless. So while I could still push the generation with 0 children to an array instead of adding another key to the hash, max(keys %generations) != $generations. I am still working the array versus hash idea, I still have to figure out everything I would have to change. I am just more comfortable dealing with hashes than arrays. Meanwhile, here is the updated script.

    #!/usr/bin/perl -l use strict; use warnings; use feature qw(say); use List::Util qw(sum max); use lib 'lib'; use Base::Nifty qw(commify); say "How many children are in the first generation?"; my $generation = <>; say "How many generations do you want to generate?"; my $generations = <>; chomp($generation,$generations); my %generations = ( 1 => $generation, ); my @distribution = (0,0,0,1,1,1,2,2,2,3,3,4,5,6); for (1..$generations) { my @generation; for (1..$generation) { my $children = $distribution[rand(@distribution)]; push @generation, $children; } $generation = sum(@generation); last if sum(@generation == 0); $generations{$_ + 1} = $generation; @generation = (); } my $max_length_generation = length(commify(max(keys %generations))); my $max_length_children = length(commify(max(values %generations))); for (sort {$a <=> $b} keys %generations) { printf "%${max_length_generation}s: %${max_length_children}s\n",$_,c +ommify($generations{$_}); }
    Have a cookie and a very nice day!
    Lady Aleena

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-04-25 08:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found