Odzyskaj moc z mocy pierwotnej

16

Wygląda na to, że wiele osób chciałoby to mieć, więc jest to kontynuacja tego wyzwania !

Definicja : potęga pierwsza jest liczbą naturalną, którą można wyrazić w postaci p n, gdzie p jest liczbą pierwszą, a n jest liczbą naturalną.

Zadanie : Biorąc pod uwagę moc pierwotną p n > 1, zwróć moc n.

Przypadki testowe :

input output
9     2
16    4
343   3
2687  1
59049 10

Punktacja : To jest . Najkrótsza odpowiedź w bajtach wygrywa.

Leaky Nun
źródło
2
Uwaga : wyzwanie to może być trywialne w niektórych językach golfowych, ale nie jest tak trywialne w przypadku niektórych głównych języków, a także języka z czerwca 2018 r., QBasic.
Erik the Outgolfer,
Czy możemy wyprowadzić True zamiast 1? Alternatywnie, float zamiast ints?
Jo King
1
@JoKing tak, tak.
Leaky Nun
@EriktheOutgolfer Wyzwanie przyjęte : D
DLosc

Odpowiedzi:

5

Python 3 , 49 bajtów

f=lambda n,x=2:n%x and f(n,x+1)or n/x<2or-~f(n/x)

Wypróbuj online!

Wyjścia Truezamiast 1 ( dozwolone przez OP ). Funkcja rekurencyjna, która wielokrotnie znajduje najniższy współczynnik, a następnie wywołuje tę funkcję z następną najniższą mocą, aż osiągnie 1. Jest to rozszerzenie mojej odpowiedzi na poprzednie pytanie.

Jo King
źródło
4

Narzędzia Bash + GNU, 22

  • 2 bajty zapisane dzięki @ H.PWiz i @Cowsquack
factor|tr -cd \ |wc -c

Wypróbuj online!

Cyfrowa trauma
źródło
1
Czy factor|sed s/\ //|wc -wdziała
H.PWiz
1
Co factor|tr -cd \ |wc -c?
Kritixi Lithos
3

dc , 50 41 bajtów

1si[dli1+dsi%0<X]dsXx[dli/dli<Y]sYdli<Yzp

Wypróbuj online!

Pobiera dane wejściowe z góry stosu (w TIO umieść dane wejściowe w nagłówku, aby załadować je na stos przed wykonaniem). Wyjścia na standardowe wyjście.

Wyjaśnienie

Zastosowane rejestry:

i: bieżący dzielnik próbny podczas Xdziałania. Później znaleźliśmy dzielnik.

X: makro dli1+dsi%0<X, które ma efekt „inkrementacji i, a następnie sprawdź moduł z wartością na stosie (który będzie oryginalnym wejściem). Jeśli nie jest zero, powtórz”.

Y: makro dli/dli<Y, które ma efekt „Dodaj do stosu kopię bieżącej góry stosu, podzieloną przez i. Powtarzaj aż do iosiągnięcia”.

Pełny program:

1si                 Initialize i
[dli1+dsi%0<X]dsXx  Define and run X
[dli/dli<Y]sY       Define Y
dli<Y               Run Y, but only if needed (if the input wasn't just i)
z                   The stack is i^n, i^(n-1), ... ,i, so print the stack depth
Sophia Lechner
źródło
Znalazłem znacznie lepsze rozwiązanie! Edytujesz teraz ...
Sophia Lechner,
3

twarz , 86 bajtów

(%d@)\$*,c'$,io>Av"[""mN*c?*m1*mp*m%*s1"$pN1p:~+p1p%%Np?%~:=/NNp+?1?-%N1?%=p%'$i?w1'%>

Brawo, dłużej niż Java!

Wypróbuj online!

Szczególnie podoba mi się sztuczka polegająca na użyciu wartości zwracanej sscanf. Normalnie wartość zwracana byłaby odrzucana, ale tutaj zawsze będzie to 1, ponieważ zawsze czytamy jedną liczbę jako dane wejściowe. Możemy to wykorzystać, przypisując jej wartość zwrotną do zmiennej 1, oszczędzając 2 bajty, które w innym przypadku byłyby wymagane do 1jednoznacznego przypisania 1.

(%d@)

\$*,c'$,io>  ( setup - assign $ to "%d", * to a number, o to stdout )
Av"[""mN*    ( set " to input and allocate space for N for int conversion )
c?*          ( calloc ?, starting it at zero - this will be the output )
m1*          ( allocate variable "1", which gets the value 1 eventually )
mp*m%*       ( p is the prime, % will be used to store N mod p )

s1"$pN       ( scan " into N with $ as format; also assigns 1 to 1 )

1p:~         ( begin loop, starting p at 1 )
  +p1p       ( increment p )
  %%Np       ( set % to N mod p )
?%~          ( repeat if the result is nonzero, so that we reach the factor )

:=           ( another loop to repeatedly divide N by p )
  /NNp       ( divide N by p in-place )
  +?1?       ( increment the counter )
  -%N1       ( reuse % as a temp variable to store N-1 )
?%=          ( repeat while N-1 is not 0 -- i.e. break when N = 1 )

p%'$i?       ( sprintf ? into ', reusing the input format string )
w1'%>        ( write to stdout )
Klamka
źródło
2

Java 8, 59 bajtów

Lambda od intdo int.

x->{int f=1,c=0;while(x%++f>0);for(;x>1;c++)x/=f;return c;}

Wypróbuj online

Jakob
źródło
2

J, 4 bajty

#@q:

q: podaje listę głównych czynników, # podaje długość listy.

Wypróbuj online!

Jonasz
źródło
2

R , 37 bajtów

length(numbers::primeFactors(scan()))

Wypróbuj online!

ngm
źródło
1
sum(x|1)jest prawie zawsze krótszy niżlength(x)
Giuseppe
2

Stax ,43) bajty

|f%

Uruchom i debuguj

Długość faktoryzacji pierwotnej.

pustkowie
źródło
5
Ahh ... przełamujesz przekreślone 4 wciąż jest normalne 4; ( mem.; P (Mimo to i tak się starzeje .. Chyba dobrze zrobione)
Kevin Cruijssen
1
Tak, nadużycie MathJax!Pamiętaj jednak, aby umieścić krzyż przed rzeczywistą liczbą bajtów, ponieważ fragment tabeli liderów może go nie rozpoznać.
user202729,
2

MATL , 3 bajty

Yfz

Wypróbuj online!

Wyjaśnienie:

     % Implicit input: 59049
Yf   % Factorize input [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
  z  % Number of non-zero elements: 10
     % Implicit output
Stewie Griffin
źródło
2

Biała spacja, 141 bajtów

[S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   T   _Read_STDIN_as_number][T    T   T   _Retrieve][S S S T  N
_Push_1][N
S S N
_Create_Label_LOOP_1][S S S T   N
_Push_1][T  S S S _Add][S N
S _Duplicate][S T   S S T   S N
_Copy_2nd_input][S N
T   _Swap_top_two][T    S T T   _Modulo][N
T   S S N
_If_0_Jump_to_Label_BREAK_1][N
S N
N
_Jump_to_Label_LOOP_1][N
S S S N
_Create_Label_BREAK_1][S S S N
_Push_0][S T    S S T   S N
_Copy_2nd_input][N
S S T   N
_Create_Label_LOOP_2][S N
S _Duplicate_input][S S S T N
_Push_1][T  S S T   _Subtract][N
T   S S S N
_If_0_Jump_to_Label_BREAK_2][S N
T   _Swap_top_two][S S S T  N
_Push_1][T  S S S _Add][S N
T   _Swap_top_two][S T  S S T   S N
Copy_2nd_factor][T  S T S _Integer_divide][N
S N
T   N
_Jump_to_Label_LOOP_2][N
S S S S N
_Create_Label_BREAK_2][S N
N
_Discard_top][T N
S T _Print_as_number]

Dodane litery S(spacja), T(tab) i N(nowa linia) tylko jako wyróżnienia.
[..._some_action]dodano tylko jako wyjaśnienie.

Wypróbuj online (tylko z surowymi spacjami, tabulatorami i nowymi wierszami).

Objaśnienie w pseudo-kodzie:

Integer n = STDIN as input
Integer f = 1
Start LOOP_1:
  f = f + 1
  if(n modulo-f == 0)
    Call function BREAK_1
  Go to next iteration of LOOP_1

function BREAK_1:
  Integer r = 0
  Start LOOP_2:
    if(n == 1)
      Call function BREAK_2
    r = r + 1
    n = n integer-divided by f
    Go to next iteration of LOOP_2

function BREAK_2:
  Print r as number to STDOUT
  Program stops with an error: Exit not defined

Przykładowy przebieg: input = 9

Command    Explanation                    Stack           Heap    STDIN   STDOUT   STDERR

SSSN       Push 0                         [0]
SNS        Duplicate top (0)              [0,0]
TNTT       Read STDIN as number           [0]             {0:9}   9
TTT        Retrieve                       [9]             {0:9}
SSSTN      Push 1                         [9,1]           {0:9}
NSSN       Create Label_LOOP_1            [9,1]           {0:9}
 SSSTN     Push 1                         [9,1,1]         {0:9}
 TSSS      Add top two (1+1)              [9,2]           {0:9}
 SNS       Duplicate top (2)              [9,2,2]         {0:9}
 STSSTSN   Copy 2nd from top              [9,2,2,9]       {0:9}
 SNT       Swap top two                   [9,2,9,2]       {0:9}
 TSTT      Modulo top two (9%2)           [9,2,1]         {0:9}
 NTSSN     If 0: Jump to Label_BREAK_1    [9,2]           {0:9}
 NSNN      Jump to Label_LOOP_1           [9,2]           {0:9}

 SSSTN     Push 1                         [9,2,1]         {0:9}
 TSSS      Add top two (2+1)              [9,3]           {0:9}
 SNS       Duplicate top (3)              [9,3,3]         {0:9}
 STSSTSN   Copy 2nd                       [9,3,3,9]       {0:9}
 SNT       Swap top two                   [9,3,9,3]       {0:9}
 TSTT      Modulo top two (9%3)           [9,3,0]         {0:9}
 NTSSN     If 0: Jump to Label_BREAK_1    [9,3]           {0:9}
NSSSN      Create Label_BREAK_1           [9,3]           {0:9}
SSSN       Push 0                         [9,3,0]         {0:9}
STSSTSN    Copy 2nd from top              [9,3,0,9]       {0:9}
NSSTN      Create Label_LOOP_2            [9,3,0,9]       {0:9}
 SNS       Duplicate top (9)              [9,3,0,9,9]     {0:9}
 SSSTN     Push 1                         [9,3,0,9,9,1]   {0:9}
 TSST      Subtract top two (9-1)         [9,3,0,9,8]     {0:9}
 NTSSSN    If 0: Jump to Label_BREAK_2    [9,3,0,9]       {0:9}
 SNT       Swap top two                   [9,3,9,0]       {0:9}
 SSSTN     Push 1                         [9,3,9,0,1]     {0:9}
 TSSS      Add top two (0+1)              [9,3,9,1]       {0:9}
 SNT       Swap top two                   [9,3,1,9]       {0:9}
 STSSTSN   Copy 2nd from top              [9,3,1,9,3]     {0:9}
 TSTS      Integer-divide top two (9/3)   [9,3,1,3]       {0:9}
 NSNTN     Jump to Label_LOOP_2           [9,3,1,3]       {0:9}

 SNS       Duplicate top (3)              [9,3,1,3,3]     {0:9}
 SSSTN     Push 1                         [9,3,1,3,3,1]   {0:9}
 TSST      Subtract top two (3-1)         [9,3,1,3,2]     {0:9}
 NTSSSN    If 0: Jump to Label_BREAK_2    [9,3,1,3]       {0:9}
 SNT       Swap top two                   [9,3,3,1]       {0:9}
 SSSTN     Push 1                         [9,3,3,1,1]     {0:9}
 TSSS      Add top two (1+1)              [9,3,3,2]       {0:9}
 SNT       Swap top two                   [9,3,2,3]       {0:9}
 STSSTSN   Copy 2nd from top              [9,3,2,3,3]     {0:9}
 TSTS      Integer-divide top two (3/3)   [9,3,2,1]       {0:9}
 NSNTN     Jump to Label_LOOP_2           [9,3,2,1]       {0:9}

 SNS       Duplicate top (1)              [9,3,2,1,1]     {0:9}
 SSSTN     Push 1                         [9,3,2,1,1,1]   {0:9}
 TSST      Subtract top two (1-1)         [9,3,2,1,0]     {0:9}
 NTSSSN    If 0: Jump to Label_BREAK_2    [9,3,2,1]       {0:9}
NSSSSN     Create Label_BREAK_2           [9,3,2,1]       {0:9}
 SNN       Discard top                    [9,3,2]         {0:9}
 TNST      Print as integer               [9,3]           {0:9}           2
                                                                                    error

Program zatrzymuje się z błędem: nie znaleziono wyjścia.

Kevin Cruijssen
źródło
1

Japt , 3 bajty

k l

Wypróbuj online!

Wyjaśnienie:

k l
k     Get the prime factors of the input
  l   Return the length
Oliver
źródło
1

Oktawa , 18 bajtów

@(x)nnz(factor(x))

Wypróbuj online!

Robi to, co mówi na puszce: Liczba niezerowych elementów w pierwotnej faktoryzacji danych wejściowych.

Stewie Griffin
źródło
1

Cjam, 5 bajtów

rimf,

Wypróbuj online!

Wyjaśnienie:

ri      take the input and convert it to an int
  mf    factors the input
    ,   take the length of the list

Wbudowane są świetne!

Chrom
źródło
Zgłoszenia muszą być domyślnie programami lub funkcjami i nie uważamy tego za funkcję . Poprawne byłyby zarówno rimf,(pełny program), jak i {mf,}(funkcja).
Dennis
@Dennis Tak, myślę, że jestem trochę zdezorientowany. Patrzyłem też wcześniej na dozwolonego stardarda io i zastanawiałem się, co właściwie powinienem zgłosić ... Naprawdę chciałem zadać pytanie na ten temat. Ale to potwierdziłeś, więc dzięki!
Chromium
1

QBasic, 51 bajtów

INPUT x
p=2
WHILE x/p>x\p
p=p+1
WEND
?LOG(x)/LOG(p)

Używa tego samego algorytmu co rozwiązanie „Odzyskaj liczbę pierwszą” w celu znalezienia podstawy, a następnie stosuje reguły logarytmów, aby uzyskać wykładnik:losol(pn)=nlosol(p).

DLosc
źródło
0

Perl 6 , 36 bajtów

{round .log/log (2..*).first: $_%%*}

Szuka pierwszego czynnika (2..*).first: $_%%*, a następnie oblicza przybliżoną wartość (logi nie uzyskają jej dokładności) i zaokrągla ją.

Wypróbuj online!

Phil H.
źródło