Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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 rifling through the Monastery: (6)
As of 2015-03-29 09:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When putting a smiley right before a closing parenthesis, do you:









    Results (630 votes), past polls