Divisorsumme aus der Primzahlfaktorisierung

11

Die Aufgabe besteht darin, die Divisorsumme einer Zahl aufgrund ihrer Primfaktorisierung zu berechnen.

Eingang

Zwei Arrays (oder etwas Äquivalentes) der Länge n , von denen eines den Primfaktor und das andere den entsprechenden Exponenten enthält.

Ausgabe

Die Summe aller Teiler (einschließlich der Zahl selbst).

Beispiel

Die Zahl 240 hat 2, 3 und 5 als Primfaktoren mit 4, 1 und 1 als jeweiligen Exponenten. Die erwartete Ausgabe wäre dann 744.

Input: [2,3,5] [4,1,1]
Output: 744

Wertung

Der kürzeste Code in Bytes gewinnt!

Wenn die Laufzeitkomplexität Ihrer Lösung O (Summe der Exponenten) und nicht O (Produkt der Exponenten) ist, kann Ihre Punktzahl mit 0,8 multipliziert werden.


Hier wurde eine ähnliche Frage gestellt , aber es war keine Herausforderung. Ich denke, das Problem ist interessant genug, um Golf zu spielen.

Der Gewinner wird an diesem Wochenende ausgewählt

Moartem
quelle
Muss das Primfaktor-Array immer das erste und das Exponenten-Array das zweite sein, oder können wir davon ausgehen, dass die Arrays umgekehrt eingegeben werden?
Sp3000
Sie können jedes Eingabeformat annehmen, das dem vorgeschlagenen
ähnlich ist
Ich kann es
momentan

Antworten:

3

Pyth, 13 Bytes * 0,8 = 10,4

*Fms^LhdhedCQ

Demonstration.

Diese Antwort funktioniert etwas anders als oben. Um die Summe der Faktoren der Primzahlen der Zahl zu berechnen, werden anstelle einer arithmetischen Formel die Faktoren explizit konstruiert und summiert.

Zum Beispiel bilden [2, 4]wir auf dem [Primzahl, Exponent] -Paar 2 ^ xab 0, 1, 2, 3, 4und geben [1, 2, 4, 8, 16], was dann zu 31 summiert wird.

Die Ergebnisse werden dann miteinander multipliziert und gedruckt.

Wenn die Potenzierung ordnungsgemäß implementiert ist oder wenn ein Zwischenergebnis-Caching vorliegt, ist dies der Fall O(sum of exponents).

isaacg
quelle
Unabhängig von der Implementierung denke ich nicht, dass es möglich ist, die erste n Potenz von a in O (n) Zeit zu berechnen , es sei denn, Sie nehmen an, dass die Multiplikation O (1) ist.
Dennis
@Dennis Nun, die Terme höherer Ordnung dominieren, also hätte es wahrscheinlich die Rutime der Multiplikation höchster Ordnung, O(n)wenn wir annehmen können, dass die Basis eine Konstante ist.
isaacg
9

CJam, 15 Bytes * 0,8 = 12

q~.{_@)#(\(/}:*

Probieren Sie es online aus . Die Eingabereihenfolge ist zuerst die Exponentenliste und dann die Liste der Primzahlen (-3 Bytes dank @Dennis) .

(p, e)Finden Sie für jedes Prim-Exponenten-Paar

(p^(e+1) - 1)/(p - 1)

dann finden Sie das Produkt von all diesen. ZB für 240 wäre das

(1 + 2 + 4 + 8 + 16)(1 + 3)(1 + 5) = 31 * 4 * 6 = 744

Abhängig davon, wie die Potenzierung implementiert wird, kann dies besser sein als O(sum of exponents).

Sp3000
quelle
6

APL, 18 13 Bytes * 0,8 = 10,4

×/(1-⊣×*)÷1-⊣

Dadurch entsteht ein dyadischer Funktionszug, der die Reihe der Faktoren links und die Exponenten rechts berücksichtigt.

×/             ⍝ Vector product of
  (1-⊣×*)      ⍝ each factor^(exponent+1)-1
         ÷1-⊣  ⍝ divided by factor-1

Probieren Sie es online aus . Beachten Sie, dass dies der gleiche Ansatz ist wie die unglaublich clevere CJam-Antwort von Sp3000 .

5 Bytes dank Dennis gespart!

Alex A.
quelle
2

TI-BASIC, 17 Bytes * 0,8 = 13,6

Verwendet auch die Methode von Sp3000, obwohl ich sie unabhängig gefunden habe. Nimmt eine Liste von Input und eine vom Homescreen.

Input E
prod(AnsAns^∟E-1)/prod(Ans-1

Verwenden von prod (zweimal ist kleiner, da wir damit die offene Klammer kostenlos verwenden können. Beachten Sie, dass diese Antwort keine leeren Arrays unterstützt, da in TI-BASIC keine leeren Arrays vorhanden sind.

lirtosiast
quelle
2

Haskell, 38 * 0,8 = 30,4

product$zipWith(\p e->(p*p^e-1)/(p-1))

Verwendung:

product$zipWith(\p e->(p*p^e-1)/(p-1)) [2,3,5] [4,1,1]
744.0

Die anonyme Funktion übernimmt (p,e)die Divisorsumme für die Summe der p^egeometrischen Reihen. Wenn Sie die beiden Listen zusammenfügen, um das Produkt zu verbinden und zu entnehmen, erhalten Sie das Ergebnis.

Ich konnte nichts kürzeres finden als den arithmetischen Ausdruck

(p*p^e-1)/(p-1)
sum$map(p^)[0..e]

Vielleicht gibt es einen Weg, das loszuwerden (\p e->_).

Die Definition der Infix-Funktion ergibt dieselbe Länge (38):

p%e=(p*p^e-1)/(p-1)
product$zipWith(%)
xnor
quelle
2

C ++, 111 80 77 Bytes * 0,8 = 61,6

int g(int*p,int*e,int n){return n?g(p+1,e+1,n-1)*(pow(*p,*e-1)-1)/(*p-1):1;}

Dies berechnet (p ^ (e + 1) -1) / (p-1) und multipliziert rekursiv alle Faktoren. Hab das vor einem Jahr selbst herausgefunden.

Vielen Dank für Ihre Hilfe. Ich habe die boolesche Verwendung im C ++ - Stil völlig vergessen.

Moartem
quelle
1
n==0vereinfacht zu !n- oder Sie könnten die Ergebnisse umkehren und einfach verwendenn
Toby Speight
2

Matlab, 53

function t=f(x,y)
s=1:prod(x.^y);t=s*~mod(s(end),s)';

Beispiel:

>> f([2 3 5], [4 1 1])
ans =
   744
Luis Mendo
quelle
Sieht aus wie Sie den 0,8 Bonus hinzufügen können
Moartem
@ Moartem Danke! Aber da bin ich mir nicht sicher. Ich berechne die Zahl sund teste dann alle möglichen Teiler von 1bis s. Es ist also (mindestens) O (s), was wahrscheinlich zwischen O (Summe der Exponenten) und O (Produkt der Exponenten) liegt
Luis Mendo
Ja, das ist richtig, es ist sogar größer als O (Produkt von Exponenten)
Moartem
1

Python 2.156

from itertools import*
from operator import*
i=input()
print sum(reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]])))

Eingang

[[2,3,5],[4,1,1]]

Ausgabe

744

Erläuterung

Dieses Programm erhält eine Liste mit 2 Listen: Faktoren und Exponenten.

i=input() # Receive list of 2 lists: i[0] for factors i[1] for exponents

Dann wird eine Liste aller möglichen Kombinationen der Exponentenliste erstellt.

[x+1 for x in i[1]] # [4,1,1]->[5,2,2] (to include last element)
map(range,[x+1 for x in i[1]]) # [[0, 1, 2, 3, 4], [0, 1], [0, 1]]
product(*map(range,[x+1 for x in i[1]])) # [(0, 0, 0), (0, 0, 1), ..., (4, 1, 1)]

und zip es mit den Faktoren:

zip(i[0],p) for p in product(*map(range,[x+1 for x in i[1]])) # [[(2, 0), (3, 0), (5, 0)], ..., [(2, 4), (3, 1), (5, 1)]]

Berechnen Sie die Faktoren nach Potenz der Exponenten:

 [a**b for a,b in zip(i[0],p)]for p in product(*map(range,[x+1 for x in i[1]])) # [[1, 1, 1], ..., [16, 3, 5]]

und multipliziere jede Liste (dies gibt uns alle Teiler):

reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]])) # [1, 5, 3, 15, ..., 240]

Zum Schluss summieren Sie alle Listen und drucken:

print sum(reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]]))) # 744
Die Krypta
quelle
Können Sie kurz erklären, was Ihr Code tut (da ich mit Python nicht vertraut bin), damit ich die Komplexität Ihres Codes beurteilen kann?
Moartem
Das ist ein kluger Ansatz, aber die Komplexität ist das Produkt der Exponenten
Moartem
@ Moartem Ja, ich habe nicht viel Zeit damit verbracht, die Komplexität zu reduzieren
TheCrypt
1

Python 3, 134 120 117

Eingabe: zwei durch Kommas getrennte Arrays, die durch Komma getrennt sind.

Beispiel:

(2,3,7,11),(4,2,3,2)
21439600
from functools import*
a=eval(input())
print(reduce(int.__mul__,(sum(x**j for j in range(y+1))for x,y in zip(*a)),1))

Mit NumPy kann auf 100 Bytes reduziert werden:

import numpy
a=eval(input())
print(numpy.product([sum(x**j for j in range(y+1))for x,y in zip(*a)]))
Trang Oul
quelle
1
Für das erste Beispiel, nur damit Sie wissen, statt den Import operatorfür die Verwendung von muleinmal, können Sie float.__mul__eine Reihe von Bytes speichern zu.
Kade
1

Gelee, nicht konkurrierend

Diese Antwort ist nicht konkurrierend, da die Herausforderung vor der Schaffung von Gelee liegt.

5 Bytes (kein Bonus)

*PÆDS

Probieren Sie es online aus!

Wie es funktioniert

*PÆDS    Main link. Left input: p (prime factors). Right input: e (exponents).

*        Elevate the prime factors to the corresponding exponents.
 P       Take the product of all powers.
  ÆD     Find all divisors of the product.
    S    Compute the sum of the divisors.

7 Bytes (5,6 Bytes nach Bonus)

*‘}’:’{P

Wie es funktioniert

×*’:’{P  Main link. Left input: p (prime factors). Right input: e (exponents).

 *       Elevate the prime factors to the corresponding exponents.
         This yields p ** e.
×        Multiply the prime factors with the corresponding powers.
         This yields p ** (e + 1).
  ’      Decrement the resulting products.
         This yields p ** (e + 1) - 1.
    ’{   Decrement the prime factors.
         This yields p - 1.
   :     Divide the left result by the right one.
         This yields (p ** (e + 1) - 1) / (p - 1).
      P  Take the product of all quotients.

Probieren Sie es online aus!

Dennis
quelle
1

APL, 12 Bytes * 0,8 = 9,6

×/1++/¨⎕*⍳¨⎕

Dies liest zwei Listen von der Tastatur, Exponenten zuerst, dh:

      ×/1++/¨⎕*⍳¨⎕
⎕:
      4 1 1
⎕:
      2 3 5
744

Erläuterung:

  • : Lesen Sie eine Liste von der Tastatur (die Exponenten)
  • ⍳¨: Generieren Sie für jede Nummer in der Liste eine Liste [1..n].
  • ⎕*: Lesen Sie eine andere Liste von der Tastatur (die Primzahlen) und erhöhen Sie jede Primzahl auf jeden der Exponenten in den entsprechenden Listen
  • +/¨: summiere jede Liste
  • 1+: Fügen Sie jedem Ergebnis eine hinzu, um das Fehlen x^0in jeder der Listen zu kompensieren
  • ×/: Nehmen Sie das Produkt der Ergebnisse
Marinus
quelle
1

Schläger (Schema), 65 * 0,8 = 52 Bytes

Gleiche Arithmetik wie alle anderen

(λ(x y)(foldl(λ(m n o)(*(/(-(expt m(+ n 1))1)(- m 1))o))1 x y))

Erläuterung:

(λ (x y)    ;defines anonymous function with two inputs
    (foldl    ;recursively applies the following function to all elements of the lists given to an argument given (foldl function argument lists lists lists...)
        (λ (m n o) (* (/ (- (expt m (+ n 1)) 1) (- m 1)) o))    ;an anonymous function representing the same arithmetic used in the CJam answer, then multiplying it with our incrementor
        1 x y))    ;the incrementor argument is 1, and the input lists are the ones provided into the original function
kronicmage
quelle
0

Python 2, 80 Bytes * 0,8 = 64

Dies setzt voraus, dass die Eingabe nacheinander eingeht. Folgt der gleichen Formel wie in der CJam-Antwort von Sp3000.

print(reduce(float.__mul__,[~-(x**-~y)/~-x for x,y in zip(input(),input())],1)) 

Wenn dies nicht erlaubt ist, verwende ich dies als Lösung, die eine Punktzahl von 84 Bytes * 0,8 = 67,2 erhält. Die Eingabe sollte durch ein Komma getrennt werden, d [2,3,5],[4,1,1]. H.

k=input()
print(reduce(float.__mul__,[~-(x**-~y)/~-x for x,y in zip(k[0],k[1])],1))

Psst. Hallo! Dies ist eine mögliche Lösung in Symbolic, an der ich arbeite:Ƥ(П([~-(x**-~y)/~-xϝx,yϊʐ(Ί,Ί)],1))

Kade
quelle
0

Mathematica, 40 Bytes

Total[Outer@@{*}~Join~(#^0~Range~#2),3]&

Ohne die Inbuilts zu verwenden, die sich mit Teilern befassen, um sich von der anderen mathematica-Lösung im Thread zu unterscheiden.

Eingabe ist (am Beispiel) [{2, 3, 5}, {4, 1, 1}]

Ein Simmons
quelle
0

Perl 5, 96 Bytes

Natürlich gewinnt das nicht, aber ich habe beschlossen, es zum Spaß zu schreiben.

Es ist eine Unterroutine:

{($b,$e)=@_;$s=1;map$s*=$b->[$_]**$e->[$_],0..@$b-1;$_=1x$s;for$j(1..$s){$i+=$j*/^(.{$j})*$/}$i}

Sehen Sie es in Aktion so:

perl -e'print sub{...}->([2,3,5],[4,1,1])'

Wie es funktioniert:

  • ($b,$e)=@_liest die eingegebenen Arrayrefs $b(Basen) und $e(Exponenten).
  • $s=1 initialisiert das Produkt.
  • map$s*=$b->[$_]**$e->[$_],0..@$b-1multipliziert $smit aufeinanderfolgenden Basisexponentenkräften. Jetzt $sist die zusammengesetzte Nummer.
  • $_=1x$sSätze $_gleich einer Folge von Einsen, $slang. $iwird bei 0 initialisiert.
  • for$j(1..$s){$i+=$j*/^(.{$j})*$/}versucht für jede Zahl $jzwischen 1 und $s, sich zu trennen $_, wenn $jZeichen beliebig oft wiederholt werden. Wenn sie kann, dann $jteilt $s, und /^(.{$j})*$/1 ist (ansonsten ist es 0) und $iwird verstärkt durch $j. Daher erhöhen wir $idie Anzahl der Partitionen in einer gleich großen Partition von $_. Wie Omar E. Pol betont , $iist dies die Nummer, die wir suchen.
  • $iam Ende kehrt zurück $i.
msh210
quelle
0

J, 14 Bytes * 0,8 = 11,2

[:*/(^>:)%&<:[

Verwendung

   f =: [:*/(^>:)%&<:[
   2 3 5 f 4 1 1
744
Meilen
quelle