2009-07-07 14 views
5

Sie sind alle Primfaktoren einer Zahl, zusammen mit ihren Multiplizitäten (höchste Mächte) gegeben.
Die Anforderung besteht darin, alle Faktoren dieser Nummer zu erzeugen.Erhalten Sie alle Faktoren einer Zahl (Iteratoren Showdown :)

Lassen Sie mich ein Beispiel geben:

Primfaktoren:

  • 2 (Leistung: 3)
  • 3 (Leistung: 1)

(was bedeutet, die Zahl ist 2^3 * 3^1 = 24)

Das erwartete Ergebnis ist:
1, 2, 3, 4, 6, 8, 12, 24

Ich denke darüber nach, dies (in C#) mit einigen verketteten benutzerdefinierten Iteratoren zu tun, einen für jeden Primfaktor, der von 0 bis zu zählen würde Macht dieser Primzahl.

Wie würden Sie das umsetzen? Verwenden Sie Ihre bevorzugte Sprache.

Dies bezieht dich auf problem #23 von Project Euler

+2

Ich weiß nicht, wie gern die Projekt Euler Administratoren von SO auszusetzen Lösungen für ihre Probleme sind. Siehe http://stackoverflow.com/questions/1010739/help-with-project-euler-200-closed. – anderstornvig

+3

In diesem Fall denke ich, es ist in Ordnung, weil die Frage nach einem Standardalgorithmus, nicht nach der Lösung des Problems fragt. Außerdem ist das Problem immer noch ziemlich einfach, und das ist nicht der beste Ansatz. – starblue

+1

+1, das ist nicht das Projekt Euler Problem überhaupt. Diese Frage ist sehr allgemein und sicherlich eine "echte" Programmierfrage. (Bezug nehmend auf die beiden Stimmen für das Schließen als "keine echte Frage".) – ShreevatsaR

Antwort

3

Betrachten Sie alle möglichen Kombinationen von Leistungen. Erhöhen Sie für jede Kombination die Primzahlen auf ihre entsprechende Stärke und multiplizieren Sie das Ergebnis.

>>> from functools import reduce 
>>> from itertools import product, starmap 
>>> from operator import mul 
>>> 
>>> def factors(prime_factors): 
...  primes, powers = zip(*prime_factors) 
...  power_combos = product(*(range(p + 1) for p in powers)) 
...  prime_combos = (zip(primes, c) for c in power_combos) 
...  return (reduce(mul, starmap(pow, c)) for c in prime_combos) 
... 
>>> sorted(factors([(2, 3), (3, 1)])) 
[1, 2, 3, 4, 6, 8, 12, 24] 

Dieser Code verwendet Python 3.0. Neben dem Aufruf an sorted werden ausschließlich Iteratoren verwendet.

Nebenbemerkung: Schade, diese Frage scheint eher unpopulär zu sein. Ich möchte z.B. Einige funktionale Lösungen werden veröffentlicht. (Ich kann später versuchen, eine Haskell-Lösung zu schreiben.)

0

ich zum ersten Mal ohne eine IDE zur Hand schießen, so könnte es einige Fehler drin sein.

struct PrimePower 
{ 
    public PrimePower(Int32 prime, Int32 power) : this() 
    { 
     this.Prime = prime; 
     this.Power = power; 
    } 

    public Int32 Prime { get; private set; } 
    public Int32 Power { get; private set; } 
} 

Und dann nur diese rekursive Funktion.

public IEnumerable<Int32> GetFactors(IList<PrimePowers> primePowers, Int32 index) 
{ 
    if (index < primePowers.Length() - 1) 
    { 
     Int32 factor = 1; 
     for (Int32 p = 0; p <= primePowers[index].Power; p++) 
     { 
      yield return factor * GetFactors(primePowers, index + 1); 
      factor *= primePowers[index].Prime; 
     } 
    } 
    else if (index = primePowers.Length() - 1) 
    { 
     Int32 factor = 1; 
     for (Int32 p = 0; p <= primePowers[index].Power; p++) 
     { 
      yield return factor * GetFactors(primePowers, index + 1); 
      factor *= primePowers[index].Prime; 
     } 
    } 
    else 
    { 
     throw new ArgumentOutOfRangeException("index"); 
    } 
} 

Es könnte auch eine Erweiterungsmethode sein und IList<PrimerPower> könnte geschwächt wahrscheinlich IEnumerable<PrimePower> mit einigen Skip() und Take() Anrufe. Ich mag es auch nicht, den Index herumzugeben, aber die Alternative wäre das Kopieren der Prime-Power-Liste für jeden Anruf. In der Konsequenz denke ich, dass eine iterative Lösung vorzuziehen ist - ich werde eine hinzufügen, wenn ich wieder eine IDE habe.

6

Haskell.

cartesianWith f xs = concatMap $ \y -> map (`f` y) xs 
factorsOfPrimeFactorization = 
    foldl (cartesianWith (*)) [1] . map (\(p, e) -> map (p^) [0..e]) 
 
> factorsOfPrimeFactorization [(2, 3), (3, 1)] 
[1,2,4,8,3,6,12,24] 

das Ergebnis zu sortieren,

import Data.List 
cartesianWith f xs = concatMap $ \y -> map (`f` y) xs 
factorsOfPrimeFactorization = 
    sort . foldl (cartesianWith (*)) [1] . map (\(p, e) -> map (p^) [0..e]) 

Perl.

sub factors { 
    my %factorization = @_; 
    my @results = (1); 
    while (my ($p, $e) = each %factorization) { 
     @results = map {my $i = $_; map $i*$_, @results} map $p**$_, 0..$e; 
    } 
    sort {$a <=> $b} @results; 
} 

print join($,, factors(2, 3, 3, 1)), $/; # => 1 2 3 4 6 8 12 24 

J.

 
    /:~~.,*/"1/{:@({.^[email protected]{:@>:)"1 ] 2 3 ,: 3 1 
1 2 3 4 6 8 12 24 

Diese alle den gleichen Algorithmus implementieren, welche die Liste zu erzeugen, ist p , p , & hellip ;, pe für jede Paar (p, und) in der Faktorisierung, und nehmen Sie das Produkt von Jede Menge wird über alle diese Listen in das kartesische Produkt eingefügt.

+0

Ich sollte beachten, dass keine dieser Sprachen wirklich ein Konzept von "Iteratoren" haben ... (Nun, Sie können in Perl gebundene Arrays machen, aber das ist ein Schmerz). Aufgrund der Faulheit von Haskell sind normale Listen jedoch Iteratoren in anderen Sprachen, aber viel einfacher zu benutzen. – ephemient

3

Wenn Sie kümmern sich nicht um die einzelnen Teilern, sondern um die Summe aller Teiler von n Sie vielleicht einen Blick auf die Divisor Function haben wollen:

Damit die Summe der Teiler von

n=p_1^{a_1}\cdot p_2^{a_2}\cdots p_k^{a_k}

ist

\frac{p_1^{a_1+1}-1}{p_1-1}\cdot\cdot\cdot\frac{p_k^{a_k+1}-1}{p_k-1}

+3

http://texify.com für Sie gesetzt. – ephemient

+0

Diese Antwort bezieht sich mehr auf das eigentliche PE-Problem als auf meine Frage; Dies ist jedoch ein großer Einblick! +1 Wie der Tipp von texify.com - ist das dein? –

-1

Sehr einfach zu tun. In der Tat habe ich einen Artikel in meinem Blog über diese Sache geschrieben. Schau dir diesen Code an.

#Application lists all factors/divisors for a number. 
targetNumber=input('What number do you want the factors for?\n> ') 
factors=[] 
for i in range(1,targetNumber): 
    if targetNumber%i==0: 
     factors.append(i) 
    elif targetNumber/i==1: 
     factors.append(targetNumber) 
     break 
print factors 

Read more

Verwandte Themen