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

12 Answers 12

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 8 hours ago
3  
Power floor What the heck – JungHwan Min 2 hours ago
1  
This post officially convinced me to learn Jelly. – Alias User 2 hours 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 12 hours ago
    
That's a nice figure. Was it generated using a builtin or created manually? – miles 12 hours ago
    
@miles It was generated using TreeForm – ngenisis 12 hours ago
    
Thanks. I don't remember ever seeing it, but evidently it's been around forever. – miles 12 hours ago

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

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

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

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

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.)

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 11 hours ago

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

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 8 hours ago
    
I'll see your 7 and raise you 4. :P – Dennis 8 hours ago
    
Wow, I did not know that was a builtin too. That takes the cake. – miles 8 hours ago

Sage, 39 bytes

lambda i:prime_powers(i)[-prime_pi(i):]

Just discovered the prime_pi function that counts the number of primes. Gotta thank the autocomplete feature!


Old attempt, 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

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

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.