#!/usr/bin/perl 

my $HISTOGRAM_WIDTH     = 20;
my $HISTOGRAM_HEIGHT    = 12;
my $HISTOGRAM_CHAR      = 'x';

my @chart = histogram(@ARGV);
print $_ for @chart;


sub histogram {
    my @nums = @_;
    my $scale_factor_y = 1;
    my $scale_factor_x = 1;
    
    # Get the highest number of @nums:
    my $highest = 0;
    for (@nums) { $highest = $_ unless $_ <  $highest }
    
    
    # Make "reasonable defaults":
    # $HISTOGRAM_HEIGHT defaults to $highest.
    # If $HISTOGRAM_HEIGHT is set and it's smaller than $highest
    # then set the $scale_factor_y to $HISTOGRAM_HEIGHT / $highest
    # and scale down all the numbers multiplying them by $scale_factor_y
    # and rounding them via sprinf:
    if ($HISTOGRAM_HEIGHT) {
        if ($highest > $HISTOGRAM_HEIGHT) {
            $scale_factor_y = $HISTOGRAM_HEIGHT / $highest;
            $_ = sprintf "%.0f ", $_ *= $scale_factor_y for @nums;
        }
    }
    else {
        $HISTOGRAM_HEIGHT = $highest;
    }
    
    # $HISTOGRAM_WIDTH defaults to the number of numbers in @nums
    # if $HISTOGRAM_WIDTH is set and it's more than twice the number of
@nums,
    # therefore allowing at least a double-character-width column, then
    # set the $scale_factor_x accordingly and use it to repeat
$HISTOGRAM_CHAR
    if ($HISTOGRAM_WIDTH) {
        if ($HISTOGRAM_WIDTH / scalar @nums >= 2) {
            $scale_factor_x = ($HISTOGRAM_WIDTH - $HISTOGRAM_WIDTH % scalar
@nums) / scalar @nums;
        }
    }
    else {
        $HISTOGRAM_WIDTH = scalar @nums;
    }

    
    # $HISTOGRAM_CHAR defaults to "*" if not set and should repeat
$scale_factor_x times
    $HISTOGRAM_CHAR = $HISTOGRAM_CHAR ? $HISTOGRAM_CHAR x $scale_factor_x :
"*" x $scale_factor_x;
    my $blank = ' ' x $scale_factor_x;
    
    
    # Build the chart:
    my @bar_chart;
    for (my $x = $HISTOGRAM_HEIGHT; $x > 0; $x--) {
        my $line = '';
        for (@nums) {
            $line .= $x <= $_ ? $HISTOGRAM_CHAR : $blank;
        }
        push @bar_chart, "$line\n";
    }
    return @bar_chart;
}
