Primäre faktorale Wurzeln

14

Inspiriert von digitalen Wurzeln, ist die faktorielle Primwurzel einer Zahl die Zahl, die entsteht, wenn Sie die Primfaktoren einer Zahl nehmen, sie addieren und den Vorgang mit der resultierenden Zahl wiederholen, bis Sie eine Primzahl erhalten ( die sich selbst als einzigen Hauptfaktor hat und somit ihre eigene faktorielle Hauptwurzel ist). Die Primfaktorwurzel von 4 ist 4, da 2 * 2 = 2 + 2, und dies ist die einzige Nicht-Primfaktor-Faktorwurzel einer ganzen Zahl größer als 1 (was ein weiterer Sonderfall ist, da sie keine Primfaktoren enthält). Die OEIS-Sequenz, die von den primären faktoralen Wurzeln gebildet wird, ist A029908 .

Die primäre faktorale Wurzel von 24 ist zum Beispiel:

24=2*2*2*3

2+2+2+3=9=3*3

3+3=6=2*3

2+3=5, and the only prime factor of 5 is 5.  Therefore, the prime factoral root of 24 is 5.  

Deine Aufgabe:

Schreiben Sie ein Programm oder eine Funktion, die die primäre faktorale Wurzel einer Eingabe-Ganzzahl findet.

Eingang:

Eine Ganzzahl, die mit einer vernünftigen Methode zwischen 2 und der größten Ganzzahl eingegeben wird, die Ihre Sprache unterstützt (einschließlich). Die Auswahl einer Sprache mit einer unangemessen niedrigen maximalen Ganzzahlgröße ist nicht zulässig (und verstößt auch gegen diese Standardlücke) ).

Ausgabe:

Eine Ganzzahl, die primäre faktorale Wurzel der Eingabe.

Testfälle:

4   -> 4
24  -> 5
11  -> 11
250 -> 17

Wertung:

Dies ist , die niedrigste Punktzahl in Bytes gewinnt!

Greif
quelle
3
Können Sie 4in den Testfällen hinzufügen , da dies eine Ausnahme darstellt und Sie es beim Testen einer Antwort leicht vergessen können?
Scottinet
Müssen wir 1 für 1 ausgeben?
Mein Pronomen ist monicareinstate
@ jemand gemäß der verknüpften OEIS-Sequenz sollte 0 für 1
scottinet
2
@someone Die Challenge besagt, dass der Input mindestens 2 sein wird.
Martin Ender
@someone Tut mir leid, dass ich eine Weile weg bin. Wie Martin sagte, besagt die Herausforderung speziell, dass die Eingabe größer als eins sein wird und daher das Verhalten, wenn die Eingabe 1 ist, undefiniert ist.
Gryphon

Antworten:

15

05AB1E , 3 Bytes

FÒO

Probieren Sie es online!

Erklärungen:

FÒO   
F    Loops <input> times + 1
 Ò   List of prime factors w/ duplicates
  O  Total sum of the list
     -- implicit output
scottinet
quelle
Dies scheint zu scheitern 4.
Shaggy
1
@ Shaggy beim Speichern von 2 Bytes
behoben
10
Macht das jemanden zum F anyoneO-Kämpfer?
Steenbergh
Zumindest war es nicht FOObar.
Magic Octopus Urn
14

Haskell , 61 Bytes

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Probieren Sie es online!

Erläuterung

until=<<((==)=<<)Nimmt eine Funktion fund wendet sie auf die Eingabe an, xbis ein Fixpunkt erreicht ist, der f xgleich ist x. primeFactorsgibt die Liste der Primfaktoren einer Zahl zurück,sum ergibt die Summe einer Liste von Zahlen.

Aber warte, warum macht until=<<((==)=<<) der Job und sieht so komisch aus?

Wenn wir annehmen f=sum.primeFactors, wäre eine natürlichere Definition until(\x->f x==x)f, weil sie untilein Prädikat (eine Funktion, die einen Booleschen Int -> IntWert zurückgibt), eine Funktion mit demselben Eingabe- und Rückgabetyp (z. B. ) und Wert dieses Typs annimmt und die Funktion dann auf die anwendet Wert, bis das Prädikat erfüllt ist.

until(\x->f x==x)fist das gleiche wie until(\x->(==)(f x)x)f, und wie es gilt, das g (h x) xist das gleiche wie (g=<<h)xwir bekommen until(\x->((==)=<<f)x)f. Nach der Eta-Konvertierung wird dies until((==)=<<f)f. Aber wenn wir jetzt behandeln (==)=<<als eine Funktion , die angewandt wird f, können wir sehen , dass until(((==)=<<)f)fwieder von der Form g (h x) x, mit g=until, h=((==)=<<)und x=f, so kann es neu geschrieben werden (until=<<((==)=<<))f. Mit Hilfe der $Bediener der Beseitigung der äußeren Klammern bekommen und Substitution fmit sum.primeFactorsAusbeuten , die Lösung von oben.

Laikoni
quelle
4
=<<((==)=<<)$Whaaaaaat.
Totalhuman
2
@icrieverytim Ich habe eine Erklärung hinzugefügt. Fühlen Sie sich frei im fragen Haskell Chatraum , wenn Sie weitere Fragen haben, wie diese Zauberei funktioniert.
Laikoni
5

Schale , 4 Bytes

ω(Σp

Probieren Sie es online!

Erläuterung:

ω(   -- apply the following function until the result no longer changes (fixpoint)
  Σ  -- sum
   p -- the list of primefactors
Laikoni
quelle
4

Pyth , 3 Bytes

usP

Probieren Sie es hier aus.

Erläuterung:

usPGQ The trailing GQ is implicit
  PG  Get prime factors
 s    Sum
u   Q Repeat until returned value no longer unique starting with the input
Erik der Outgolfer
quelle
Haben Sie vergessen, Ihre Erklärung zu aktualisieren?
MCMastery
1
@MCMastery Nein, der Code und die Erklärung sind gleich. The trailing GQ is implicit
Totalhuman
@ MCMastery, was ich Cri everytim sagte
Erik der Outgolfer
4

Python 2 , 84 Bytes

f=lambda n,d=2:n>1and(n%d and f(n,d+1)or d+f(n/d))
i=input()
exec'i=f(i);'*i
print i

Probieren Sie es online!

ovs
quelle
Das mag eine ziemlich blöde Frage sein, aber wie funktioniert das f=lambda n,d=2:n>1and(n%d and f(n,d+1)or d+f(n/d))? Ich habe noch nie in Python programmiert (hauptsächlich Java und C #), daher bin ich mir nicht sicher, was das Ergebnis dieser Funktion ist. Ändert diese Funktion die Eingabe nund gibt sie anschließend zurück, oder ähnelt sie einem Booleschen Wert, bei dem n>1and(n%d and f(n,d+1)or d+f(n/d))entweder 0 oder 1 oder 0 oder noder etwas anderes angegeben ist? Ich versuche zu visualisieren, wie ein Port davon in Java / C # aussehen würde, kann dies aber nicht, da ich Python-Lambdas wie dieses im Allgemeinen nicht wirklich verstehe.
Kevin Cruijssen
1
@ KevinCruijssen das entspricht n>1 ? (n%d!=0 ? f(n, d+1) : d+f(n/d)) : n>1. Im Allgemeinen x and yist äquivalent zu x ? y : x. x and y or zentspricht x ? y : zin den meisten Fällen.
OVS
1
@KevinCruijssen ein Java-Port wäre sowas f=(n,d=2)->n>1?n%d>0?f(n,d+1):d+f(n/d):0.
OVS
Ach ok Danke für die Erklärung, jetzt macht es viel mehr Sinn. Und ich erinnere mich, x and ydass ich auch x ? y : xaus JavaScript stamme. Vielen Dank!
Kevin Cruijssen
4

Java 8, 175 144 142 141 Bytes

n->{for(int i,t=n,x;;n=t){for(i=2;i<t;t=t%i++<1?0:t);if(t>1|n<5)return n;for(t=0,i=1;i++<n;)for(;n%i<1;n/=i,t+=x)for(x=i;x>9;x/=10)t+=x%10;}}

-1 Byte dank @Nevay .

Im Gegensatz zu einzelnen Bytes in einigen der Golfsprachen ist Java ziemlich ausführlich für Prim-Checks, Prim-Faktoren, Ziffernsummen und dergleichen, so dass ich vermute, dass weniger als 200 nicht allzu schäbig sind.
Kann höchstwahrscheinlich noch gespielt werden, indem Schleifen kombiniert werden und keine getrennte rekursive Methode für die Ziffernsumme verwendet wird .

Erläuterung:

Probieren Sie es hier aus.

n->{                // Method with integer as both parameter and return-type
  for(int i,        //  Index-integer `i`
          t=n,      //  Temp integer `t`, starting at the input `n`
          x;        //  Temp integer `x`
      ;             //  Loop (1) indefinitely
      n=t){         //    After every iteration, replace `n` with the value `t`
    for(i=2;        //   Reset `i` to 2
        i<t;        //   Inner loop (2) from 2 to `t` (exclusive)
        t=t%i++<1?  //    If `t` is divisible by `i`:
           0        //     Set `t` to 0
          :         //    Else:
           t        //     Leave `t` the same
    );              //   End of inner loop (2)
    if(t>1          //   If `t` is not 0 (it means it's a prime),
       |n<5)        //   or if `n` is below 5 (for edge-cases `4` and 'prime' `1`)
      return n;     //    Return `n` as result
    for(t=0,        //   Reset `t` to 0
        i=1;        //   Reset `i` to 1
        i++<n;)     //   Inner loop (3) from 2 to `n` (inclusive)
      for(;n%i<1;   //    Inner loop (4) as long as `n` is divisible by `i`
          n/=i,     //      After every iteration: Divide `n` by `i`,
          t+=x)     //      and increase `t` by `x`
        for(x=i;    //     Reset `x` to `i`
            x>9;    //     Inner loop (5) as long as `x` contains more than 1 digit
            x/=10)  //       After every iteration, remove the trailing digit
          t+=n%10;  //      Increase `t` with the trailing digit of `n`
                    //     End of inner loop (5) (implicit / single-line body)
                    //    End of inner loop (4) (implicit / single-line body)
                    //   End of inner loop (3) (implicit / single-line body)
  }                 //  End of loop (1)
}                   // End of method
Kevin Cruijssen
quelle
6
+1 für die Mühe, eine Erklärung so ausführlich zu verfassen, als wäre dies eine Golfsprache.
Mein Pronomen ist monicareinstate
@jemand Danke! Da mich in der Vergangenheit einmal jemand nach einer Erklärung meiner Java-Antwort gefragt hat, habe ich sie allen meinen Antworten hinzugefügt. :)
Kevin Cruijssen
i,t=n,xsieht aus wie es in Python gehört, haha
ETHproductions
@ETHproductions Hehe, schade, ich muss noch das Leading hinzufügen int (im Gegensatz zu Python). ;)
Kevin Cruijssen
Sie können i++<nanstelle von verwenden ++i<=n.
Nevay
3

Netzhaut , 30 Bytes

{+`(\1|\b11+?\B)+$
$1;$#1$*
;

Ein- und Ausgabe in unary .

Probieren Sie es online!(Führt der Einfachheit halber eine Dezimal- / Unär-Konvertierung durch.)

Erläuterung

{+`(\1|\b11+?\B)+$
$1;$#1$*

Das { weist Retina an, das gesamte Programm in einer Schleife auszuführen, bis ein vollständiger Durchlauf die Zeichenfolge nicht mehr ändert, dh bis ein fester Punkt erreicht ist. Folglich berechnet das Programm selbst einen Schritt zum Summieren der Primfaktoren des aktuellen Wertes.

Diese Stufe berechnet selbst die Primfaktorisierung der Eingabe. Das +ist ähnlich wie, {aber schleift nur diese Phase, bis es aufhört, die Zeichenfolge zu ändern. Der Regex versucht, den endgültigen Lauf von 1s abzugleichen, indem er wiederholt denselben Teilstring (dh den Faktor) abgleicht. Die Art und Weise, wie dies gemacht wird, ist aufgrund der Vorwärtsreferenz etwas verworren \1. Bei der ersten Iteration hat die Gruppe 1noch nichts erfasst und \1schlägt daher bedingungslos fehl. Stattdessen müssen wir \b11+?\Bdie kleinstmögliche Teilzeichenfolge abgleichen, die am Anfang des Laufs beginnt, mindestens zwei 1s enthält und nicht den gesamten Lauf abdeckt. Nachfolgende Iterationen können diese Alternative aufgrund der nicht mehr verwenden \b. Bei allen weiteren Iterationen stimmen wir also überein\1 , dh immer wieder dieselbe Teilzeichenfolge. Dieser Prozess muss genau das Ende der Zeichenkette treffen ($ treffen ), um sicherzustellen, dass wir den tatsächlichen Teiler erfasst haben. Der Vorteil dieses etwas kniffligen Ansatzes ist, dass die Gruppe 1genau n / d verwendet wurde Mal verwendet wurde, dh was nach dem Aufteilen des Divisors d übrig bleibt .

Wir ersetzen diese Übereinstimmung durch d ( $1), ein Trennzeichen ;und n / d ( $#1$*wobei $#1Kopien von eingefügt werden 1, wobei $#1die Anzahl der von der Gruppe erstellten Erfassungen angegeben wird 1).

Dieser Prozess wird beendet, sobald der letzte Lauf in der Zeichenfolge selbst eine Primzahl ist, da die Regex dann nicht mehr übereinstimmt.

;

Alles, was wir tun müssen, um die Primzahlen zu summieren, ist, alle Trennzeichen zu entfernen.

Martin Ender
quelle
3

Ohm v2 , 4 Bytes

·ΘoΣ

Probieren Sie es online!

Erläuterung:

·Θ    evaluate the block until the result returned has already been seen
   Σ  sum
  o   the full prime factorization
Cinaski
quelle
2

Eigentlich 7 Bytes

⌠w♂πΣ⌡Y

Probieren Sie es online!

Erläuterung:

⌠w♂πΣ⌡Y
⌠    ⌡Y  do this until output stops changing (fixed-point combinator)
 w         factor into [prime, exponent] pairs
  ♂π       product of each pair
    Σ      sum of products
Mego
quelle
2

R + pracma , 53 Bytes

function(n){for(i in 1:n)n=sum(pracma::factors(n))
n}

Probieren Sie es online! (R-Geige)

R hat bisher keine Primfaktoren builtin, aber zahlreiche Pakete ( pracma, numbersusw.) zu tun, so dass ich eine bequem kurzen gepflückt.

Giuseppe
quelle
1

Gelee , 6 Bytes

Diese Antwort verwendet eine von Jellys vielen eingebauten Primfaktor-Funktionen repeat until the results are no longer unique.

ÆfSµÐL

Probieren Sie es online!

Sherlock9
quelle
Ich glaube, Sie waren überfordert, aber angesichts Ihrer Herangehensweise bin ich mir nicht sicher, ob diese Antwort funktioniert
caird coinheringaahing
@cairdcoinheringaahing Ich habe gerade seine Antwort (oder besser gesagt das Python-Äquivalent) von 1 auf 100000 überprüft und es funktioniert. Ich denke, dies 1ist der einzige Fall, in dem die Anzahl der erforderlichen Schritte gleich ist n(was in Ordnung ist; 1wir müssen sie nur einmal ausführen), und es scheint keine Fälle zu geben, in denen die Anzahl der Schritte größer ist als n(d. H es scheint keine Gegenbeispiele zu geben). Na ja, ich war überfordert: D
Sherlock9
Nun, es passiert. Obwohl +1 genau derselbe Code war, an den ich gedacht habe, als ich diese Herausforderung sah
caird coinheringaahing
Die Summe der Primfaktoren von n ist immer kleiner oder gleich n, was es ziemlich einfach macht zu beweisen, dass n immer mehr als genug ist.
Chris
1

MATL , 6 Bytes

Verwendet die Idee von Scottinet, öfter als nötig zu loopen . Danke auch an Shaggy für den Hinweis auf einen Fehler, der jetzt korrigiert wurde.

t:"Yfs

Probieren Sie es online!

Erläuterung

t       % Take input (implicit). Duplicate
:"      % Do the following that many times
  Yf    %   Array of prime factors
  s     %   Sum of array
        % End (implicit). Display (implicit)
Luis Mendo
quelle
Dies scheint zu scheitern 4.
Shaggy
@ Shaggy Danke! Daran arbeiten
Luis Mendo
@ Shaggy Jetzt gelöst
Luis Mendo
1

PowerShell , 124 Byte

function f($a){for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}}}
for($x=$args[0];$l-ne$x){$l=$x;$x=(f($x))-join'+'|iex}$x

Probieren Sie es online!

In PowerShell ist keine Primfaktor-Funktion integriert, daher wird der Code aus meiner Antwort auf Prime Factors Buddies verwendet für die Durchführung der Faktorisierungsberechnungen der (die oberste Zeile) verwendet.

Die zweite Zeile ist das Fleisch dieses Programms. Wir nehmen eine Eingabe von $argsin $x, dann forSchleife , bis $list -not equal zu $x. (Die erste Iteration $list $nullund$x ist eine Ganzzahl, wir werden also mindestens einmal eine Schleife durchführen.)

Innerhalb der Schleife legen wir $l = $xfest, ob wir das Ende der Schleife erreicht haben oder nicht. Dann bekommen wir die Faktoren von $xmit f($x), -joindenen zusammen mit +und |iexihnen (kurz für Invoke-Expressionund ähnlich eval). Das ist wieder in gespeichert $x. Somit haben wir das "Ende" erreicht, an dem die zusammengezählte Primfaktorisierung wieder zu sich selbst zurückkehrt. Dann platzieren wir einfach $xin der Pipeline und die Ausgabe ist implizit.

AdmBorkBork
quelle
0

Mathematica, 35 Bytes

#//.x_:>Tr[1##&@@@FactorInteger@x]&

Probieren Sie es online!

(Mathematik unterstützt nicht Tr. Ich muss es manuell implementieren.)

user202729
quelle
4
1##&ist eine Abkürzung für Timesund FixedPointkann fast immer gekürzt werden mit //.:#//.x_:>Tr[1##&@@@FactorInteger@x]&
Martin Ender
@ MartinEnder Danke! Ich hätte es schon wissen sollen Times, aber ich habe nichts über den FixedPointTrick gewusst .
user202729
Ihr Code ist in Mathematica geschrieben. Dies ist keine Mathematikfunktion. Sie sollten entweder den Namen der Sprache in Mathematica oder Tr in Total
J42161217
@ {no one} Entschuldigung, der Name der Sprache (Mathematik) war ein Fehler. {i cri evritime} hat das behoben.
user202729
0

Ruby , 63 Bytes

->n{n.times{n=n.prime_division.map{|x|x.reduce:*}.sum};n}

Probieren Sie es online!

Verwendet das -rprimeFlag für +6 Bytes, um Prime # prime_division zu verwenden .

prime_divisiongibt Paare von zurück [prime, exponent](zum Beispiel für 24 haben wir die Faktoren [2, 2, 2, 3], die es gibt [[2, 3], [3, 1]]), also multiplizieren wir in jedem Schritt einfach die Mitglieder dieser Paare und summieren die Ergebnisse.

Snack
quelle
0

Javascript (ES6), 63 Byte

f=n=>(q=(p=(m,x)=>m<x?0:m%x?p(m,x+1):x+p(m/x,x))(n,2))^n?f(q):q
<input id=i type=number min=0 value=0 oninput="o.innerText=f(i.value)">
<p id=o></p>

Ungolfed:

f=n=>(                  // Recursive function `f`
    p=(m,x=2)=>(        //   Recursive function `p`, used to sum prime factors
        m<x?            //     If m (the number to be factored) is less than x (the current
            0           //     iteration), return 0
        :m%x?           //     Else if m doesn't divide x
            p(m,x+1)    //     run the next iteration
        :               //     Else (if m divides x)
            x+p(m/x,x)  //     Divide m by x and repeat the current iteration
    ),
    q=p(n),             //   Set q to the sum of the prime factors of n
    q^n?                //   If q != n then
        f(q)            //     repeat f with q
    :                   //   else
        q               //     return q
)
Herman L
quelle
0

Java 8, 101 Bytes

n->{for(int i=n;i-->0;n=f(n,2));return n;}int f(int n,int d){return n>1?n%d>0?f(n,d+1):d+f(n/d,2):0;}

Port of @ovs 's erstaunliche Antwort auf Python 2 .

Erläuterung:

Probieren Sie es hier aus.

n->{                  // Method with integer as both parameter and return-type
  for(int i=n;i-->0;  //  Loop the input amount of times
    n=f(n,2)          //   And change `n` that many times with a separate method call
  );                  //  End of loop
  return n;           //  Then return the integer `n` as result
}                     // End of method

int f(int n,int d){   // Separated method with 2 integer parameters and integer return-type
                      // (`d` is 2 when we initially call this recursive-method)
  return n>1?         //  If input `n` is larger than 1:
    n%d>0?            //   And it's not divisible by `d`:
     f(n,d+1)         //    Do a recursive-call with `n, d+1`
    :                 //   Else:
     d                //    Sum `d` with
      +f(n/d,2)       //    a recursive call with `n/d, 2`
   :                  //  Else:
    0;                //   Simply return 0
}                     // End of separated method
Kevin Cruijssen
quelle