in reply to Re: OT: Finding Factor Closest To Square Root
in thread OT: Finding Factor Closest To Square Root

I rearranged it a bit so you can just plug in your factor list and it will figure out what your number is. Note that in this case, the closest value is 5*7, but it returns 3*19.
use strict; use warnings; use List::Util qw[ reduce ]; my @pfs = ( 3,5,7,19 ); my $num = reduce { $a * $b } @pfs; my $root = sqrt $num; print "N=$num, R=$root\n"; #the rest is the same as you had it
Here's a fix:
use strict; use warnings; use List::Util qw[ reduce ]; my @pfs = ( 3,5,7,19 ); my $num = reduce { $a * $b } @pfs; my $root = sqrt $num; print "N=$num, R=$root\n"; my $near = reduce{ abs($root - $a * $b) < abs($root - $a) ? $a*$b : $a } reverse @pfs; print abs($root - $near) > abs($root - ($num/$near)) ? $num/$near : $near ;

Caution: Contents may have been coded under pressure.

Replies are listed 'Best First'.
Re^3: OT: Finding Factor Closest To Square Root
by BrowserUk (Patriarch) on Feb 19, 2005 at 00:32 UTC

    One testcase was never going to hack it. I should have thought of your method, but I was too busy trying to figure out why CPAN would install M::B::F.


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      Mine isn't perfect, either. Try 2,2,2,7,19,19, for example. I'm pretty sure the problem requires an exhaustive search of all combinations.

      Caution: Contents may have been coded under pressure.

        Yeah! I'm reaching a similar conclusion..now if only I could work out to use Algorithm::Loops, it'd be done in a trice :)


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.
        Roy Johnson,
        I am pretty sure that all combinations need to be considered initially as you can see by my contributions elsewhere in this thread. It is possible to short-circuit early in some cases though, which may be a significant improvement. For instance - here are some ideas:
        • Prior to determining the product of each combination, you can abort if you have already seen this combination
        • When determining the product of each combination, you can abort if the value is greater than the sqrt
        • If combinations are gathered left to right, once you have determined that the product of a given combination is greater than the sqrt() all future combinations that include this combination can be skipped
        I have only chosen to implement the first 1 in my Perl code. This is because my combinations aren't gathered left to right. I will see if I can't modify the code to take advantage of all 3 of these short cuts.

        Cheers - L~R