Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re^3: OT: Finding Factor Closest To Square Root

by Roy Johnson (Monsignor)
on Feb 28, 2005 at 15:01 UTC ( [id://435076]=note: print w/replies, xml ) Need Help??


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

You're right. I had an erroneous understanding: that the closest factor that included top_factor would be paired with the closest factor that didn't. Instead, it's paired with the closest factor on the other side of root that doesn't include top_factor. So you have to check both sides of root. Here's a fixed version:
use strict; use warnings; use List::Util qw[ reduce ]; my $num; # Used in sub, but could be passed if you wanted sub closest { # Args are target and factor-list my ($target, @factors) = @_; # Take the biggest factor my $top_factor = pop @factors; # Find multiple of that factor closest to (and above) target my $guess = int($target) - $target % $top_factor + $top_factor; # Oscillate around the target, looking at multiples of top_factor # until you get one that divides the product my $i; for ($i = $top_factor; $num % $guess; $i += $top_factor) { $guess += ( $target <=> $guess ) * $i; } # Check the complementary factor my $complement = $num / $guess; # Look for a multiple of $top_factor between the last guess on the # other side of sqrt and $complement my $direction = ($target <=> $guess); my $new_guess = $guess + $direction * $i; while (($complement <=> $new_guess) == $direction and $num % $new_ +guess) { $new_guess += $top_factor * $direction; } if ($new_guess and $num % $new_guess == 0 and (($complement <=> $new_guess) == $direction)) { $guess = $new_guess; $complement = $num/ $guess; } abs($target - $complement) < abs($target - $guess) ? $complement : $guess ; } my @pfs = (3, 5, 16381, 77951); # Compute product of factors our ($a, $b); $num = reduce { $a * $b } @pfs; my $root = sqrt $num; print "N=$num, R=$root\n"; print closest($root, 1, @pfs), "\n";

Caution: Contents may have been coded under pressure.

Replies are listed 'Best First'.
Re^4: OT: Finding Factor Closest To Square Root
by Limbic~Region (Chancellor) on Feb 28, 2005 at 19:07 UTC
    Roy Johnson,
    What am I missing - it still produces 77951 as the answer?

    Cheers - L~R

      I fixed a different bug and re-broke this! Ok, it's updated and works at least for your example. Gotta update my benchmark code, too.

      Caution: Contents may have been coded under pressure.
        Roy Johnson,
        Ok, now it is broken for 26816652079 which has a prime factorization of (7,19,109,691,2677). The correct answer should be 91903.

        Cheers - L~R

        Update:Impressive! After your last updated, not only does it now get all 50_000 answers correct - it is within a few seconds of my Inline::C solution. A proper benchmark might find it faster.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://435076]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-18 19:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found