2009-07-07 10 views
5

Dostajesz wszystkie czynniki pierwsze liczby, wraz z ich wielokrotnościami (najwyższymi mocami).
Wymaga się przedstawienia wszystkich czynników o tej liczbie.Uzyskaj wszystkie czynniki liczby (iteratory showdown :)

Podam przykład:

czynniki pierwsze:

  • 2 (power: 3)
  • 3 (moc: 1)

(co oznacza, że ​​liczba jest 2^3 * 3^1 = 24)

Spodziewany wynik to:
1, 2, 3, 4, 6, 8, 12, 24

Zastanawiam się nad zrobieniem tego (w języku C#) z kilkoma łańcuchowymi niestandardowymi iteratorami, po jednym dla każdego współczynnika podstawowego, który będzie liczony od 0 do moc tej liczby pierwszej.

Jak to wdrożyć? Użyj swojego preferowanego języka.

Wiąże się to z problem #23Project Euler

+2

Nie wiem, jak lubi Administratorzy Projekt Euler są SO narażając rozwiązania ich problemów. Zobacz http://stackoverflow.com/questions/1010739/help-with-project-euler-200-closed. – anderstornvig

+3

W tym przypadku myślę, że jest OK, ponieważ pytanie wymaga standardowego algorytmu, a nie rozwiązania problemu. Ponadto problem jest nadal dość łatwy, a to nie jest najlepsze podejście. – starblue

+1

+1, to w ogóle nie jest problemem Projektu Euler. To pytanie jest bardzo ogólne, a na pewno "prawdziwe" pytanie programistyczne. (Odnosząc się do dwóch głosów za zamknięcie go jako "nie jest to prawdziwe pytanie"). – ShreevatsaR

Odpowiedz

3

Rozważ wszystkie możliwe kombinacje mocy. Dla każdej kombinacji podnieś liczby pierwsze do odpowiedniej mocy i pomnóż wynik.

>>> 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] 

Ten kod wykorzystuje język Python 3.0. Oprócz połączenia z sorted, używa wyłącznie iteratorów.

Uwaga boczna: szkoda, że ​​to pytanie wydaje się raczej niepopularne. Chciałbym zobaczyć np. niektóre funkcjonalne rozwiązania są publikowane. (Mogę spróbować napisać później rozwiązanie Haskell.)

0

ja najpierw strzelać bez IDE pod ręką, więc nie mogą być pewne błędy tam.

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; } 
} 

A potem tylko ta funkcja rekursywna.

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"); 
    } 
} 

To może być również metodę rozszerzenia i IList<PrimerPower> mógłby prawdopodobnie osłabiony do IEnumerable<PrimePower> z kilkoma Skip() i Take() połączeń. Nie podoba mi się również przekazywanie indeksu, ale alternatywą byłoby kopiowanie listy mocy głównej dla każdego połączenia. W konsekwencji myślę, że preferowane byłoby rozwiązanie iteracyjne - dodam je, jeśli będę miał IDE ponownie.

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] 

Aby posortować wyniki,

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 

Wszystkie one realizować ten sam algorytm, który jest do utworzenia listy P , p , i hellip ;, Pe dla każdego parę (p, e) w rozkładzie, i weź produkt każdy zestaw w produkcie kartezjańskim na wszystkich tych listach.

+0

Należy zauważyć, że żaden z tych języków nie ma naprawdę pojęcia "iteratorów" ... (cóż, możesz tworzyć powiązane tablice w Perlu, ale to jest ból). Jednak z powodu lenistwa Haskella, normalne listy są jak iteratory w innych językach, ale o wiele łatwiejsze w użyciu. – ephemient

3

Jeśli nie dbają o pojedynczych dzielników, ale o sumę wszystkich dzielników n warto rzucić okiem na Divisor Function:

ten sposób sumę dzielników

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

jest

\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 dla Ciebie. – ephemient

+0

Ta odpowiedź odnosi się bardziej do rzeczywistego problemu PE niż do mojego pytania; jednak jest to świetny wgląd! +1 Podobnie jak w przypadku strony texify.com - czy to jest twoje? –

-1

bardzo proste do zrobienia. W rzeczywistości napisałem artykuł na moim blogu na ten temat. Sprawdź ten kod.

#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

Powiązane problemy