Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

A prime power is a positive integer n that can be written in the form n = pk where p is a prime and k is a positive integer. For example, some prime powers are [2, 3, 5, 4, 9, 25, 8, 27, 125].

Next, consider prime powers of 2. These are [2, 4, 8, 16, ...] and can be written in the form 2k. They would all be included when considering prime powers beneath 20. However, 16 is the maximal prime power with a base prime of 2 in that range. A prime power pk is maximal in a range if it is the highest power of p in that range. We are only interested in the maximal prime power in each range so all lower prime powers must be excluded.

Your goal is to write a function or program that takes a positive integer n and outputs the maximal prime powers in the range [2, 3, 4, ..., n].

Thanks to @Peter Taylor for clarifying the definition of maximal prime power and more.

Rules

  • This is so make your code as short as possible.
  • The maximal prime powers may be output in any order but there must be no duplicates.

Test cases

n      result
1      []
2      [2]
3      [2, 3]
4      [3, 4]
5      [3, 4, 5]
6      [3, 4, 5]
7      [3, 4, 5, 7]
20     [5, 7, 9, 11, 13, 16, 17, 19]
50     [11, 13, 17, 19, 23, 25, 27, 29, 31, 32, 37, 41, 43, 47, 49]
100    [11, 13, 17, 19, 23, 25, 29, 31, 37, 41, 43, 47, 49, 53, 59, 61, 64, 67, 71, 73, 79, 81, 83, 89, 97]
10000  <1229 results>
       [101, 103, 107, 109, 113, 127, 131, 137, 139, 149, ..., 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973]

The full list of maximal prime powers for 10000 can be found here.

share|improve this question

15 Answers 15

Jelly, 7 4 bytes

æḟÆR

Try it online!

How it works

æḟÆR  Main link. Argument: n

  ÆR  Prime range; yield all primes in [1, ..., n].
æḟ    Power floor; round n down to the nearest power of each prime in the range.
share|improve this answer
    
Oh so obvious once one sees it! – Jonathan Allan yesterday
9  
Power floor What the heck – JungHwan Min yesterday
1  
This post officially convinced me to learn Jelly. – Alias User yesterday
    
These synthetic-golfing languages are getting silly – smci 1 hour ago

Mathematica, 44 43 40 bytes

Saved 4 bytes thanks to miles and Martin Ender

n#^⌊#~Log~n⌋&/@Select[Range@n,PrimeQ]

(x=Prime@Range@PrimePi@#)^⌊x~Log~#⌋&

and are the 3 byte characters U+230A and U+230B representing \[LeftFloor] and \[RightFloor], respectively.

Explanation:

enter image description here

Pure function. # is short for Slot[1] which represents the first argument to the Function. PrimePi@# counts the number of primes less or equal to #, Range@PrimePi@# is the list of the first PrimePi[#] positive integers, and so Prime@Range@PrimePi@# is the list of primes less than or equal to # (this is one byte shorter than Select[Range@#,PrimeQ]). The symbol x is Set equal to this list, then raised to the Power ⌊x~Log~#⌋, which is the list of Floor[Log[n,#]] for each n in x. In Mathematica, raising a list to the Power of another list of the same length results in the list of the powers of their corresponding elements.

share|improve this answer
    
I thought Range@#~Select~PrimeQ would be shorter than Prime@Range@PrimePi@# ... but it's a tie – Greg Martin yesterday
    
That's a nice figure. Was it generated using a builtin or created manually? – miles yesterday
    
@miles It was generated using TreeForm – ngenisis yesterday
    
Thanks. I don't remember ever seeing it, but evidently it's been around forever. – miles yesterday

MATL, 13 bytes

ZqG:!^tG>~*X>

Try it Online!

Explanation

        % Implicitly grab the input as a number (N)
Zq      % Get an array of all primes below N
G:!     % Create an array from [1...N]
^       % Raise each prime to each power in this array which creates a 2D matrix
        % where the powers of each prime are down the columns
tG>~    % Create a logical matrix that is TRUE where the values are less than N
*       % Perform element-wise multiplication to force values > N to zero
X>      % Compute the maximum value of each column
        % Implicitly display the resulting array
share|improve this answer

Jelly, 12 9 bytes

RÆEz0iṀ$€

Try it online! (method is too slow for the 10000 case).

How?

Builds the list of pk in order of p.

RÆEz0iṀ$€ - Main link: n                      e.g. 7
R         - range(n)                          [1 ,2  ,3    ,4  ,5      ,6    ,7]
 ÆE       - prime factor vector (vectorises)  [[],[1],[0,1],[2],[0,0,1],[1,1],[0,0,0,1]]
   z0     - transpose with filler 0           [[0,1,0,2,0,1,0],[0,0,1,0,0,1,0],[0,0,0,0,1,0,0],[0,0,0,0,0,0,1]]
       $€ - la$t two links as a monad, for €ach       ^             ^                   ^                   ^
     i    -     first index of                        4             3                   5                   7
      Ṁ   -     maximum                       [4,3,5,7]
share|improve this answer

Jelly, 8 bytes

ÆR*ÆE€»/

Try it online!

How it works

ÆR*ÆE€»/  Main link. Argument: n

ÆR        Prime range; yield all primes in [1, ..., n].
   ÆE€    Prime exponents each; yield the exponents of 2, 3, 5, ... of the prime
          factorization of each k in [1, ..., n].
          For example, 28 = 2² × 3⁰ × 5⁰ × 7¹ yields [2, 0, 0, 1].
  *       Exponentiation; raise the elements of the prime range to the powers
          of each of the exponents arrays.
      »/  Reduce the columns by maximum.
share|improve this answer

Pyth, 13 bytes

m^ds.lQdfP_TS

Try it here!

        f   S -  filter(v, range(1, input))
         P_T  -   is_prime(T)
m             - map(v, ^)
    .lQd      -    log(input, d)
   s          -   int(^)
 ^d           -  d ** ^

I haven't played with Pyth in a while so any golfing tips are appreciated.

share|improve this answer

CJam, 21 20 bytes

Saved 1 byte thanks to Martin Ender

ri_){mp},f{\1$mLi#}p

Try it online!

Explanation

ri                    e# Read an integer from input (let's call it n)
  _                   e# Duplicate it
   ){mp},             e# Push the array of all prime numbers up to and including n
         f{           e# Map the following block to each prime p:
           \          e#   Swap the top two elements of the stack
            1$        e#   Copy the second element down in the stack. Stack is now [p n p]
              mL      e#   Take the base-p logatithm of n
                i     e#   Cast to int (floor)
                 #    e#   Raise p to that power
                  }   e# (end of map block)
                   p  e# Print
share|improve this answer

05AB1E, 15 12 bytes

ƒNpiN¹N.nïm,

Try it online!

Explanation

ƒ             # for N in [0 ... input]
 Npi          # if N is prime
    N         # push N
     ¹N.n     # push log_N(input)
         ï    # convert to int
          m   # raise N to this power
           ,  # print
share|improve this answer

I couldn't get a shorter Mathematica solution than ngenisis's solution, but I thought I'd offer a couple of (hopefully interesting) alternative approaches.

Mathematica, 65 bytes

#/#2&@@@({#,#}&/@Range@#~Select~PrimeQ//.{a_,b_}/;a<=#:>{b a,b})&

First we use {#,#}&/@Range@#~Select~PrimeQ to build a list of all primes in the appropriate range, but with ordered pairs of each prime, like { {2,2}, {3,3}, ...}. Then we operate on that list repeatedly with the replacement rule {a_,b_}/;a<=#:>{b a,b}, which multiplies the first element of the ordered pair by the second until the first element exceeds the input. Then we apply #/#2&@@@ to output, for each ordered pair, the first element divided by the second. (They end up sorted by the underlying prime: an example output is {16, 9, 5, 7, 11, 13, 17, 19}.)

Mathematica, 44 bytes

Values@Rest@<|MangoldtLambda@#->#&~Array~#|>&

The von Mangoldt function Λ(n) is an interesting number theory function: it equals 0 unless n is a prime power pk, in which case it equals log p (not log n). (These are natural logs, but it won't matter.) Thus MangoldtLambda@#->#&~Array~# creates an array of rules { 0->1, Log[2]->2, Log[3]->3, Log[2]->4, Log[5]->5, 0->6, ... } whose length is the input integer.

We then turn this list of rules into an "association" using <|...|>. This has the effect of retaining only the last rule with any given left-hand value. In other words, it will throw away Log[2]->2 and Log[2]->4 and Log[2]->8 and keep only Log[2]->16 (assuming that the input is between 16 and 31 for this example). Therefore the only remaining right-hand sides are the maximal prime powers—except for the one remaining rule 0->n, where n is the largest non-prime-power up to the input integer. But Rest throws that undesired rule away, and Values extracts the right-hand sides from the rules in the association. (They end up sorted as above.)

A slightly longer (46 bytes) version, which counts the number of appearances of each log p and then exponentiates to convert to the maximal prime powers:

E^(1##)&@@@Rest@Tally[MangoldtLambda~Array~#]&
share|improve this answer
1  
Neat use of associations. They've been out since 2014 but I don't think they've seen much use in golfing. Very useful to know it replaces identical keys with values from left to right. – miles yesterday

Jelly, 9 bytes

Ræl/ÆF*/€

One byte longer than my other answer, but finishes for input 10,000 is a couple of seconds.

Try it online!

How it works

Ræl/ÆF*/€  Main link. Argument: n

R          Range; yield [1, ..., n].
 æl/       Reduce by least common multiple.
    ÆF     Factor the LCM into [prime, exponent] pairs.
      */€  Reduce each pair by exponentiation.
share|improve this answer
    
There is also a 7 byte version in Jelly that finishes quickly. – miles yesterday
    
I'll see your 7 and raise you 4. :P – Dennis yesterday
    
Wow, I did not know that was a builtin too. That takes the cake. – miles yesterday

Brachylog, 24 bytes

This is my first time using Brachylog, and I know some things could have been done in shorter ways, but I'm happy that it even works :D

{I≥N~^Xhṗ:N×>I∧0<~tX}ᶠ^ᵐ

Try it online! (Return values are ordered by their base primes)

Explanation:

{...................}ᶠ        #Find all possible results of what's inside.
 I≥N                          #Input I is >= than a number N.
   N~^X                       #X is a list [A,B], where A^B=N.
      Xhṗ                     #The first element of X (A) is prime.
         :N×>I                #That same element (A), multiplied by N is 
                              #greater than I - This means that N is the
                              #maximal power for A.
              ∧0<~tX          #The last element of X (B) is greater than 0.
                              #Now we have a list of lists [A,B]
                      ^ᵐ      #Apply ^ to all of those lists
share|improve this answer

JavaScript (ES6), 118 120 119 114 112 105 bytes

(n,r)=>(r=k=>[...Array(k-1)].map((_,i)=>i+2),r(n).filter(q=>r(q).every(d=>q%d|!(d%(q/d)*(q/d)%d)&q*d>n)))

Suggestions welcome. This is kind of long, but it seemed worth posting because it does all the divisibility testing explicitly rather than using built-ins related to primes.

Notes:

  • A natural number q is a prime power <=> all of q's divisors are powers of the same prime <=> for any d which divides q, one of d and q/d is a divisor of the other.
  • If q is a power of p, q is maximal <=> q * p > n <=> q * d > n for every nontrivial divisor d of q.
share|improve this answer

Bash + GNU utilities, 74 bytes

seq $1|factor|sed "s@.*: \(\w*\)\$@\1;l($1);l(\1);print \"/^p\"@"|bc -l|dc

Try it online!

The input number is passed as an argument. The output is printed to stdout. (As is customary, stderr is ignored.)

Sample output:

./maximalprimepowers 100 2>/dev/null
64
81
25
49
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97

./maximalprimepowers 10000 2>/dev/null | wc -l
1229

Here's how it works:

Call the argument N.

seq generates all the numbers from 1 to N, and factor factors them all.

The regex in the call to sed identifies those lines where the number is a prime P, and replaces those lines with lines that are of the form `

P;l(N);l(P);print "/^p"

(where P and N are replaced by their actual numerical values, and everything else is copied literally, even the quotes and semicolons, and the string print).

These lines are fed as input to bc -l; bc prints the values of the three indicated numbers, each followed by a newline, and then prints the characters /^p . (In bc, l(x) denotes the natural logarithm of x.) JK K

The strings that bc prints are then fed as input to dc; dc prints the value of each P^(log(N)/log(P)) using integer arithmetic (truncating); that's the greatest power of P that is <= N.

One thing that's glossed over above is what happens to lines that are produced by factor that don't correspond to primes. Those lines don't match the regex in the call to sed, so no replacement is done on those. As a result, those lines start with a number followed by a colon, which generates an error when fed as input to bc. But bc just prints to stderr then, which we ignore; it doesn't print anything to stdout. By default, stderr is ignored on PPCG.

share|improve this answer

PHP, 101 93 91 88 bytes

just a little bit of real maths ...

for($n=$argv[$i=1];$n>$j=$i++;$j?:$r[$p=$i**~~log($n,$i)]=$p)for(;$i%$j--;);print_r($r);

breakdown

for($n=$argv[$i=1];     // loop $i from 2 to $n
    $n>$j=$i++;             // 0.: init $j to $i-1
    $j?:                    // 2. if $i is prime
        $r[$p=$i**~~log($n,$i)]=$p) // 3. add maximum power to results
    for(;$i%$j--;);         // 1. prime check (if $i is prime, $j will be 0)
print_r($r);            // print results
share|improve this answer

Sage, 43 bytes

lambda i:[x^int(ln(i,x))for x in primes(i)]

Maps each prime in the range primes(i) to its maximal prime power. ln is just an alias of log so it accepts alternate bases although its name suggests it can only use base e.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.