Thread Factorize that number to primes (8 answers)
Opened by data at 2004-05-03 21:01

esskar
 2004-05-03 23:05
#81966 #81966
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
@E|B: Deine Funktion ist nicht die richtige!

naja, schnell ist anders, aber wenn du die Liste vorberechnen lässt und als Datei einbindest, kann es gehen

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/perl

use strict;
use warnings;

use vars qw/@PRIMES/;

use constant L => 1024;   # 2^10
use constant M => 1048584;   # 2^20 + 8

@PRIMES = sieve();

print "     24 = ", fact(24), "\n";
print "  13289 = ", fact(13289), "\n";
print " 524288 = ", fact(524288), "\n";
print "1048576 = ", fact(1048576), "\n";
print "4194304 = ", fact(4194304), "\n";

sub sieve # Generating array of test primes via sieve of Eratosthenes
{
  # sieve of Eratosthenes

  my @retval = ();
  my @primes = ();
  my ($i, $j) = (0, 0);

  for $i (0 .. M) { $primes[$i] = 1; } # set all as prime

  for $i (1 .. L) # go thru all primes and
  {
     if($primes[$i]) # throw out the multiples
     {
        for($j = 2*$i*($i+1); $j <= M; $j += 2*$i+1) { $primes[$j] = 0; }  # multiples are not prime
     }
  }

  # populate the vector of test divisors

  $i = 0;
  $retval[$i++] = 2; # set the even prime

  for $j (1 .. M)
  {
     $retval[$i++] = 2*$j + 1 if $primes[$j];
  }

  return @retval;
}

sub fact
{
  my ($n) = @_;
  my $retval = 0;

  for (@PRIMES)
  {
     unless($n % $_)
     {
        $n /= $_;
        $retval += $_;
        redo
     }
  }

  print "M to small\n" if $n > 1;

  return $retval;
}


btw. ich hatte die Funktion im Original irgendwann mal in C geschrieben; in C ist sie bei weitem schneller; zum vergleich:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int sieve(unsigned long d[])
{
// sieve of Eratosthenes

  unsigned int a, i;                   // loop ind, exponent

  /* the array prime[x] test for primality of 2*x + 1 */
  char prime[M+1];                     // byte array for flags

  for (a = 0; a <= M; a++)             // initialize ...
     prime[a] = 1;                   // ... to everything prime
  for (a = 1; a <= L; a++)             // go thru all primes and
     if (prime[a])                     // throw out the multiples
        for (i = 2*a*(a+1); i <= M; i += 2*a+1)
           prime[i] = 0;              // multiples are not prime

// populate the vector of test divisors

  i = 0;
  d[i++] = 2;                          // set the even prime

  for (a = 1; a<=M; a++)
     if (prime[a])
        d[i++] = 2*a + 1;              // set the uneven primes

  return i;
}

View full thread Factorize that number to primes