Recover the power from the prime power

16

1

It seems that many people would like to have this, so it's now a sequel to this challenge!

Definition: a prime power is a natural number that can be expressed in the form pn where p is a prime and n is a natural number.

Task: Given a prime power pn > 1, return the power n.

Testcases:

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

Scoring: This is . Shortest answer in bytes wins.

Leaky Nun

Posted 2018-06-20T23:37:26.540

Reputation: 45 011

2Note: This challenge might be trivial in some golfing languages, but it's not so trivial for some mainstream languages, as well as the language of June 2018, QBasic. – Erik the Outgolfer – 2018-06-20T23:55:27.300

Can we output True instead of 1? Alternatively, float instead of ints? – Jo King – 2018-06-21T00:33:00.720

1@JoKing yes, yes. – Leaky Nun – 2018-06-21T00:34:51.580

@EriktheOutgolfer Challenge accepted :D

– DLosc – 2018-06-22T04:46:09.640

Answers

7

05AB1E, 2 bytes

Òg

Try it online!

Cheese

Posted 2018-06-20T23:37:26.540

Reputation: 71

2Welcome to PPCG! – Oliver – 2018-06-21T01:12:42.210

1

Welcome indeed! For anyone reading this: Ò: Push list of prime factors (with duplicates) and g: Push length.

– Kevin Cruijssen – 2018-06-21T10:04:41.777

5

Python 3, 49 bytes

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

Try it online!

Outputs True instead of 1 (as allowed by OP). Recursive function that repeatedly finds the lowest factor and then calls the function again with the next lowest power until it reaches 1. This is an extension of my answer to the previous question.

Jo King

Posted 2018-06-20T23:37:26.540

Reputation: 38 234

4

Pyth, 2

Count prime factors:

lP

Online test.

Digital Trauma

Posted 2018-06-20T23:37:26.540

Reputation: 64 644

4

Bash + GNU utilities, 22

  • 2 bytes saved thanks to @H.PWiz and @Cowsquack
factor|tr -cd \ |wc -c

Try it online!

Digital Trauma

Posted 2018-06-20T23:37:26.540

Reputation: 64 644

1Does factor|sed s/\ //|wc -w work? – H.PWiz – 2018-06-21T10:32:16.337

1What about factor|tr -cd \ |wc -c? – user41805 – 2018-06-21T11:10:08.203

4

Python 2, 37 bytes

f=lambda n,i=2:i/n or(n%i<1)+f(n,i+1)

Try it online!

Counts factors. Apparently I wrote the same golf in 2015.

Narrowly beats out the non-recursive

Python 2, 38 bytes

lambda n:sum(n%i<1for i in range(1,n))

Try it online!

xnor

Posted 2018-06-20T23:37:26.540

Reputation: 115 687

3

dc, 50 41 bytes

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

Try it online!

Takes input from the top of the stack (in TIO, put the input in the header to load it onto the stack before execution). Outputs to stdout.

Explanation

Registers used:

i: the current trial divisor, while X is running. Later, the divisor we've found.

X: the macro dli1+dsi%0<X, which has the effect "increment i, then check the modulus with the value on the stack (which will be the original input). If it's not zero, repeat".

Y: the macro dli/dli<Y, which has the effect "Add to the stack a copy of the current top of the stack, divided by i. Repeat until i is reached."

Full 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

Posted 2018-06-20T23:37:26.540

Reputation: 1 200

I found a much better solution! Editing now... – Sophia Lechner – 2018-06-21T01:13:55.443

3

face, 86 bytes

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

Hooray, longer than Java!

Try it online!

I am particularly fond of the trick of using the return value of sscanf. Normally the return value would be discarded, but here it will always be 1, because we're always reading a single number as input. We can take advantage of this by assigning its return value to the variable 1, saving the 2 bytes that would otherwise be required to assign 1 to 1 explicitly.

(%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 )

Doorknob

Posted 2018-06-20T23:37:26.540

Reputation: 68 138

3

Attache and Wolfram Language (Mathematica) polyglot, 10 bytes

PrimeOmega

Try Attache online! Try Mathematica online!

Simply a builtin for computing the number of prime factors N has.

Explanation

Since N = pk, Ω(N) = Ω(pk) = k, the desired result.

Conor O'Brien

Posted 2018-06-20T23:37:26.540

Reputation: 36 228

2

Jelly, 3 2 bytes

Æḍ

Try it online!

Erik the Outgolfer

Posted 2018-06-20T23:37:26.540

Reputation: 38 134

2

Java 8, 59 bytes

A lambda from int to int.

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

Try It Online

Jakob

Posted 2018-06-20T23:37:26.540

Reputation: 2 428

2

J, 4 bytes

#@q:

q: gives the list of prime factors, # gives the length of the list.

Try it online!

Jonah

Posted 2018-06-20T23:37:26.540

Reputation: 8 729

2

R, 37 bytes

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

Try it online!

ngm

Posted 2018-06-20T23:37:26.540

Reputation: 3 974

1sum(x|1) is nearly always shorter than length(x) – Giuseppe – 2018-06-21T15:56:35.420

2

Stax, \$\require{cancel}\xcancel 4 3\$ bytes

|f%

Run and debug it

Length of prime factorization.

wastl

Posted 2018-06-20T23:37:26.540

Reputation: 3 089

5

Ahh.. you're breaking the crossed out 4 is still regular 4 ;( meme. ;p (It was getting old anyway though.. So well done I guess)

– Kevin Cruijssen – 2018-06-21T07:47:50.927

1$\text{Yay, MathJax abuse!}$ But remember to put the cross before the actual bytecount otherwiae the leaderboard snippet may not be able to recognize it. – user202729 – 2018-06-22T08:53:38.240

2

MATL, 3 bytes

Yfz

Try it online!

Explanation:

     % 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

Posted 2018-06-20T23:37:26.540

Reputation: 43 471

2

Whitespace, 141 bytes

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

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Explanation in pseudo-code:

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

Example run: 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 stops with an error: No exit found.

Kevin Cruijssen

Posted 2018-06-20T23:37:26.540

Reputation: 67 575

2

Brachylog, 2 bytes

ḋl

Try it online!

Explanation

ḋ        Prime decomposition
 l       Length

Fatalize

Posted 2018-06-20T23:37:26.540

Reputation: 32 976

1

Python 2, 62 bytes

def f(n,p=2,i=0):
	while n%p:p+=1
	while n>p**i:i+=1
	return i

Try it online!

Nothing fancy here.

Chas Brown

Posted 2018-06-20T23:37:26.540

Reputation: 8 959

1

You can save three bytes by making it a full program: Try it online!

– dylnan – 2018-06-21T00:23:51.193

1

Japt, 3 bytes

k l

Try it online!

Explanation:

k l
k     Get the prime factors of the input
  l   Return the length

Oliver

Posted 2018-06-20T23:37:26.540

Reputation: 7 160

1

Oliver

Posted 2018-06-20T23:37:26.540

Reputation: 7 160

1

Haskell, 27 bytes

f n=sum$(0^).mod n<$>[2..n]

Try it online!

Counts factors. Compare:

Haskell, 28 bytes

f n=sum[1|0<-mod n<$>[2..n]]

Try it online!

Haskell, 28 bytes

f n=sum[0^mod n i|i<-[2..n]]

Try it online!

Haskell, 30 bytes

f n=sum[1|i<-[2..n],mod n i<1]

Try it online!

xnor

Posted 2018-06-20T23:37:26.540

Reputation: 115 687

1

Octave, 18 bytes

@(x)nnz(factor(x))

Try it online!

Does what it says on the tin: Number of non-zero elements in the prime factorization of the input.

Stewie Griffin

Posted 2018-06-20T23:37:26.540

Reputation: 43 471

1

Cjam, 5 bytes

rimf,

Try it Online!

Explanation:

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

Builtins are great!

Chromium

Posted 2018-06-20T23:37:26.540

Reputation: 201

Submissions must be programs or functions by default, and we don't consider this a function. Both rimf, (full program) and {mf,} (function) would be valid.

– Dennis – 2018-06-21T20:49:36.960

@Dennis Yeah, I think I'm kind of confused on that. I also looked at allowed stardard io before and wondered about what I should actually submit... I actually wanted to ask a question on meta about that. But you confirmed that, so thanks!

– Chromium – 2018-06-22T03:19:33.583

1

QBasic, 51 bytes

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

Uses the same algorithm as the "Recover the prime" solution to find the base, then uses rules of logarithms to get the exponent: \$log(p^n) = n \cdot log(p)\$.

DLosc

Posted 2018-06-20T23:37:26.540

Reputation: 21 213

0

Gaia, 2 bytes

ḍl

Try it online!

Mr. Xcoder

Posted 2018-06-20T23:37:26.540

Reputation: 39 774

0

JavaScript (ES6), 37 bytes

f=(n,k=2)=>n%k?n>1&&f(n,k+1):1+f(n/k)

Try it online!

Arnauld

Posted 2018-06-20T23:37:26.540

Reputation: 111 334

0

Perl 6, 36 bytes

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

Looks for the first factor (2..*).first: $_%%*, then from there calculates the approximate value (logs won't get it exact) and rounds it.

Try it online!

Phil H

Posted 2018-06-20T23:37:26.540

Reputation: 1 376

0

Pari/GP, 8 bytes

bigomega

Try it online!

bigomega(x): number of prime divisors of x, counted with multiplicity.


Pari/GP, 14 bytes

n->numdiv(n)-1

Try it online!

alephalpha

Posted 2018-06-20T23:37:26.540

Reputation: 23 988

0

Racket, 31 bytes

(car(cdr(perfect-power(read))))

Try it online!

potato

Posted 2018-06-20T23:37:26.540

Reputation: 339

0

Perl 6, 18 bytes

{+grep($_%%*,^$_)}

Try it online!

Anonymous code block that gets a list of factors and coerces it to a number.

Jo King

Posted 2018-06-20T23:37:26.540

Reputation: 38 234

0

JavaScript (Node.js), 29 bytes

f=(n,k=n)=>--k&&!(n%k)+f(n,k)

Try it online! Note: Stack overflows for larger inputs.

Neil

Posted 2018-06-20T23:37:26.540

Reputation: 95 035

0

F#, 91 bytes

let rec d n c v=if v=n then c else d(n/v)(c+1)v
let p n=d n 1(Seq.find(fun x->n%x=0){2..n})

Try it online!

p gets the prime factor. d recursively divides the target value until it's equal to the prime factor and returns the count from that.

Ciaran_McCarthy

Posted 2018-06-20T23:37:26.540

Reputation: 689