Beefy Boxes and Bandwidth Generously Provided by pair Networks Frank
go ahead... be a heretic
 
PerlMonks  

Not very perlish?

by Anonymous Monk
on Jun 10, 2002 at 09:23 UTC ( #173057=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

My program accepts 3 percentile inputs ($pre, $amble, $post ) which should sum to 100, if they don't I wish to correct them such that they do.

If the sum is greater than 100 I wish to favour amble, then pre, then post.

If the sum is less than 100, post takes up the slack;

The following achieves my aim, but it doesn't seem very elegant (perlish), and I am sure that it can be improved upon.

$pre = (shift) % 100; $amble = (shift) % 100; $post = (shift) % 100; if ($pre + $amble + $post != 100 ) { $pre = 100 - $amble if ( $amble + $pre > 100 ); $post = 100 - ($amble + $pre) if ( $pre + $amble + $post != 100 ); } print "$pre + $amble + $post = ", <br> $pre + $amble + $post , "\n";

When is p the complement of ch?
When in the company of Erlish!

Comment on Not very perlish?
Download Code
Re: Not very Perlish? (note the capital P ;)
by frankus (Priest) on Jun 10, 2002 at 10:13 UTC
    As a wearer of size eleven paratrooper boots, I think elegance is over rated. As cranky Perl coder, my philostophy is this:
    If it works, it's Perl.

    If you still want a more Perlish way, you're throwing down the gauntlet for Perl Golf. Bad anonymous monk!.

    my @items = map {$_ % 100 } @_; my $sum = 100; $sum -= $_ for @items[0..2]; $items[ $sum<0?0:2 ] += $sum unless $sum == 0;

    --

    Brother Frankus.

    ¤

Re: Not very perlish?
by Abigail-II (Bishop) on Jun 10, 2002 at 11:37 UTC
    Here's a Perl program that takes N numbers and scales them such that their sum becomes 100, but their ratios remain the same.

    Abigail

    #!/usr/bin/perl use strict; use warnings 'all'; my $sum = 0; $sum += $_ for @ARGV; map {$_ *= 100 / $sum} @ARGV; print "@ARGV\n";
Re: Not very perlish?
by particle (Vicar) on Jun 10, 2002 at 11:56 UTC
    If the sum is greater than 100 I wish to favour amble, then pre, then post.

    If the sum is less than 100, post takes up the slack;

    i think this will do it. if amble is greater than 100, it's an error. otherwise, an array will be returned with the values as you specify above. i used the values directly from the @_ array, to make sure they were constant. if you have trouble, i can de-obfuscate it.

    sub verify_percentile { my $tot = 100; $_[1] > $tot && die('out of range'); return $_[0] + $_[1] > $tot ? ( $tot - $_[1], $_[1], 0) : (@_[0,1], $tot - $_[0] - $_[1]); }

    ~Particle *accelerates*

Re: Not very perlish?
by talexb (Canon) on Jun 10, 2002 at 14:30 UTC
    Here's another approach.
    { # Arguments to this function are in the order Pre, # Amble, and Post. Not sure why we're doing a modulo # 100 operation here unless it's a substitution for # the int() operator. my $Sum = 0; my @Values = map { $_ % 100, $Sum += $_, $_; } @_; if ( $Sum > 100 ) { # "If the sum is greater than 100 I wish to favour # amble, then pre, then post." my @Index = ( 1, 0, 2 ); my $ThisElement = 0; # Reduce values in selected order by brute force. # This could be done by calculation instead. while ( $Sum > 100 ) { $Values[ $Index[ $ThisElement++ % 3 ] ]--; $Sum--; } } elsif ( $Sum < 100 ) { # "If the sum is less than 100, post takes up the # slack;" $Values[ 2 ] -= 100 - $Sum; } # In all cases, return the variables, modified or not. return ( @Values ); }
    Code is not tested.

    --t. alex

    "Nyahhh (munch, munch) What's up, Doc?" --Bugs Bunny

(tye)Re: Not very perlish?
by tye (Cardinal) on Jun 10, 2002 at 16:48 UTC

    I think you have an excellent start. You can simplify it a fair bit, however:

    my $pre = (shift) % 100; my $amble = (shift) % 100; my $post = (shift) % 100; $pre = 100 - $amble if( $amble + $pre > 100 ); $post = 100 - ($amble + $pre); print "$pre + $amble + $post = ", $pre + $amble + $post , "\n";
    That should produce the same results modulo round-off errors.

            - tye (but my friends call me "Tye")
Re: Not very perlish?
by Anonymous Monk on Jun 10, 2002 at 23:54 UTC

    One post - replies to several good brethren and sisthren.

    >Re: Not very Perlish? (note the capital P ;) - Noted!

    >If it works, it's Perl. - True - but I wish to extend my knowledge

    > you're throwing down the gauntlet for Perl Golf. - Que? "Perl Golf"?

    my @items = map {$_ % 100 } @_; my $sum = 100; $sum -= $_ for @items[0..2]; $items[ $sum<0?0:2 ] += $sum unless $sum == 0;

    Neat! i *think* I understand this.

    Brother Frankus. - Thankyou.


    Here's a Perl program that takes N numbers and scales them such that their sum becomes 100, but their ratios remain the same.

    - Probably what I was unconciously seeking.

    Abigail - Thankyou. This is what I will be using!


    ~Particle *accelerates* - I need to sanitise all inputs and continue to run. - probably an easy mod IF I understood how yours worked :)


    Not sure why we're doing a modulo 100 operation here unless it's a substitution for the int() operator.

    Seemed like the easy way to
    a) force values <100
    b) deal with non-integer inputs?

    --t. alex - Thankyou.


    > I think you have an excellent start - Is this "faint praise" ? :)

    >. You can simplify it a fair bit, however: - And in a couple of (now you pointed them out!) very obvious ways.

    - tye (but my friends call me "Tye") - Thanyou! (May I call you Tye?:)


    When is P the compliment of ch?
    When they are in the company of Erlish!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://173057]
Approved by Zaxo
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2014-04-18 01:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (460 votes), past polls