All pastes #167630 Raw Edit

bobbymcr

public text v1 · immutable
·published 2006-09-12 04:46 UTC
rendered paste body
#!perl -w
use strict;

my $INITIAL_SEED_COUNT = 100;
my ($T_SEED, $T_SEEDLING, $T_MATURE) = (0, 1, 2);
my $PCT_GERMINATE = .04;
my $PCT_MATURE = .25;
my $SEEDS_PRODUCED = 1000;
my $MAX_SEED_AGE = 8;
my $MAX_PLANT_AGE = 5;
my $END_YEAR = 10;

my $population =
{
    'seeds'      => InitArray($INITIAL_SEED_COUNT, $MAX_SEED_AGE),
    'germinated' => InitArray(0, $MAX_PLANT_AGE),
    'mature'     => InitArray(0, $MAX_PLANT_AGE)
};

for (my $year = 0; $year < $END_YEAR; ++$year)
{
    GrowPopulation($population);
    print "At the end of year $year:\n";
    PrintPopulation($population);
}

sub PrintPopulation
{
    PrintAge($population->{'seeds'}, 'Seeds');
    print "\n";
    PrintAge($population->{'germinated'}, 'Germinated');
    print "\n";
    PrintAge($population->{'mature'}, 'Mature');
    print '-' x 40 . "\n";
}

sub PrintAge
{
    my $array = shift;
    my $heading = shift;
    print "$heading\n";
    for my $i (0 .. $#{$array})
    {
        my $amt = $array->[$i];
        print "Age $i:" . ' ' x (12 - length($amt)) . "$amt\n";
    }
    print 'Total: ' . Sum($array) . "\n";
}

sub GrowPopulation
{
    my $population = shift;
    
    # everyone ages, dead items are removed
    UpdateAge($population->{'seeds'});
    UpdateAge($population->{'germinated'});
    UpdateAge($population->{'mature'});

    # things that sprout/produce do so
    my $newSeeds   = ProduceSeeds($population->{'mature'}, $SEEDS_PRODUCED);
    my $newSprouts = Grow($population->{'seeds'}, InitArray(0, $MAX_PLANT_AGE), $PCT_GERMINATE, 1);
    my $newPlants  = Grow($population->{'germinated'}, InitArray(0, $MAX_PLANT_AGE), $PCT_MATURE, 0);
    
    # add newly grown things to their proper age positions
    $population->{'seeds'}->[0] += $newSeeds;
    Combine($population->{'germinated'}, $newSprouts);
    Combine($population->{'mature'}, $newPlants);
}

sub ProduceSeeds
{
    my $mature = shift;
    my $toProduce = shift;
    
    return Sum($mature) * $toProduce;
}

sub Grow
{
    my $items = shift;
    my $grown = shift;
    my $pctToGrow = shift;
    my $resetAge = shift;
    
    my $total = Sum($items);    
    my $numToGrow = int($total * $pctToGrow);
    
    for my $i (0 .. $#{$items})
    {
        if ($items->[$i] < $numToGrow)
        {
            $grown->[$resetAge ? 0 : $i] = $items->[$i];
            $items->[$i] = 0;
            $numToGrow -= $items->[$i];
        }
        else
        {
            $grown->[$resetAge ? 0 : $i] = $numToGrow;
            $items->[$i] -= $numToGrow;
            last;
        }
    }
    
    return $grown;
}

sub Sum
{
    my $array = shift;
    my $sum = 0;
    
    for my $x (@$array)
    {
        $sum += $x;
    }
    
    return $sum;
}

sub Combine
{
    my $destination = shift;
    my $other = shift;
    
    for my $i (0 .. $#{$destination})
    {
        $destination->[$i] += $other->[$i];
    }
}

sub UpdateAge
{
    my $array = shift;
    # everyone ages (shifts over 1 'aging column' to the right)
    unshift(@$array, 0);
    # these ones died
    pop(@$array);
}

sub InitArray
{
    my $init = shift;
    my $length = shift;
    my $array = [ $init ];

    for my $i (1 .. $length - 1)
    {
        $array->[$i] = 0;
    }

    return $array;
}