12
\$\begingroup\$

tl;dr: Output the values where the reduced prime factorization leader changes.

Every positive integer has a unique prime factorization. Let's call the reduced prime factorization just the list of multiplicity of the prime factors, ordered by the size of the factors. For instance, the reduced prime factorization of 1980 is [2, 2, 1, 1], because 1980 = 2 * 2 * 3 * 3 * 5 * 11.

Next, let's record how often each reduced prime factorization happens, over integers in [1, 2, ..., n]. For instance, in [1, 2, ..., 10], the following reduced prime factorizations occur:

[1]: 4 (2, 3, 5, 7)
[2]: 2 (4, 9)
[1, 1]: 2 (6, 10)
[]: 1 (1)
[3]: 1 (8)

We'll call the leader up to n the reduced prime factorization that occurs the most often over [1, 2, ..., n]. Therefore, the reduced prime factorization leader for n = 10 is [1]. Ties will be broken by the size of the largest integer less than or equal to n with that reduced prime factorization, with smaller largest integer being better. For instance, up to n = 60, the reduced prime factorizations [1] and [1, 1] occur 17 times each. The maximum integer in that range giving [1, 1] is 58, while the maximum integer giving [1] is 59. Therefore, with n = 60, the reduced prime factorization leader is [1, 1].

I'm interested in the values of n where the reduced prime factorization leader changes. Those are the values of n where the reduced prime factorization leader is different from the reduced prime factorization leader up to n-1. As an edge case, we will say that the leadership changes at n = 1, because a leader does not exist for n = 0.

Your challenge is to output.

An initial sequence of the desired output is:

1, 3, 58, 61, 65, 73, 77, 1279789, 1280057, 1280066, 1280073, 1280437, 1280441, 1281155, 1281161, 1281165, 1281179, 1281190, 1281243, 1281247, 1281262, 1281271, 1281313, 1281365

Allowed output styles are:

  • Infinite output.
  • The first k leader changes, where k is the input.
  • The kth leader change, where k is the input.

k may be zero or one indexed.

This is code-golf. If you're not sure about anything, ask in the comments. Good luck!

\$\endgroup\$
4
  • \$\begingroup\$ What about the leader changes with value at most / less than k? \$\endgroup\$
    – user202729
    Commented Feb 17, 2018 at 9:04
  • \$\begingroup\$ @user202729 I'm going to say no - that makes the challenge a bit too different. \$\endgroup\$
    – isaacg
    Commented Feb 17, 2018 at 9:07
  • \$\begingroup\$ Since you have defined the idea for positive integers you might want to allow people to start the sequence at either 1 or 3. (or change "Those are the values of n where the reduced prime factorization leader is different from the reduced prime factorization leader up to n-1") \$\endgroup\$ Commented Feb 17, 2018 at 10:32
  • \$\begingroup\$ @JonathanAllan I'm not changing things, but I clarified the relevant part of the challenge. \$\endgroup\$
    – isaacg
    Commented Feb 18, 2018 at 8:46

5 Answers 5

3
\$\begingroup\$

Husk, 18 bytes

m←ġ(←►Lk=mȯmLgpṫ)N

Try it online! This prints the infinite list. The link truncates the result to the first 7 values, since the program is quite inefficient and times out after that on TIO.

The parentheses are ugly, but I don't know how to get rid of them.

Explanation

m←ġ(←►Lk=mȯmLgpṫ)N  No input.
                 N  The list of natural numbers [1,2,3,4,..
  ġ(            )   Group into slices according to this function.
                    Each slice corresponds to a run of numbers with equal return values.
    ←►Lk=mȯmLgpṫ    Function: from n, compute the reduced factorization leader in [1..n].
                     As an example, take n = 12.
               ṫ     Reversed range: [12,11,10,9,8,7,6,5,4,3,2,1]
         m           Map over this range:
              p       Prime factorization: [[2,2,3],[11],[2,5],[3,3],[2,2,2],[7],[2,3],[5],[2,2],[3],[2],[]]
             g        Group equal elements: [[[2,2],[3]],[[11]],[[2],[5]],[[3,3]],[[2,2,2]],[[7]],[[2],[3]],[[5]],[[2,2]],[[3]],[[2]],[]]
          ȯmL         Take length of each run: [[2,1],[1],[1,1],[2],[3],[1],[1,1],[1],[2],[1],[1],[]]
       k=            Classify by equality: [[[2,1]],[[1],[1],[1],[1],[1]],[[1,1],[1,1]],[[2],[2]],[[3]],[[]]]
                     The classes are ordered by first occurrence.
     ►L              Take the class of maximal length: [[1],[1],[1],[1],[1]]
                     In case of a tie, ► prefers elements that occur later.
    ←                Take first element, which is the reduced factorization leader: [1]
                    The result of this grouping is [[1,2],[3,4,..,57],[58,59,60],[61,62,63,64],..
m←                  Get the first element of each group: [1,3,58,61,65,73,77,..
\$\endgroup\$
2
  • \$\begingroup\$ Why does ►= not work. Does maxBy not prefer later elements? \$\endgroup\$
    – H.PWiz
    Commented Feb 17, 2018 at 14:42
  • \$\begingroup\$ @H.PWiz The problem is that in case of a tie, I need to prefer the maximizing element whose first occurrence in the reversed range is the latest possible, or equivalently, whose last occurrence in the increasing range is the earliest possible. ►= does neither. \$\endgroup\$
    – Zgarb
    Commented Feb 17, 2018 at 14:46
1
\$\begingroup\$

JavaScript (ES6), 120 bytes

Returns the N-th leader change, 1-indexed.

N=>(F=m=>N?F((F[k=(D=(n,d=2,j)=>d>n?j:n%d?D(n,d+1)+(j?[,j]:[]):D(n/d,d,-~j))(++n)]=-~F[k])>m?F[N-=p!=k,p=k]:m):n)(n=p=0)

Demo

let f =

N=>(F=m=>N?F((F[k=(D=(n,d=2,j)=>d>n?j:n%d?D(n,d+1)+(j?[,j]:[]):D(n/d,d,-~j))(++n)]=-~F[k])>m?F[N-=p!=k,p=k]:m):n)(n=p=0)

for(let n = 1; n <= 7; n++) {
  console.log('a(' + n + ') = ' + f(n))
}

Commented

Helper function D(), returning the reduced prime factorization of n in reverse order:

D = (n, d = 2, j) =>             // n = input, d = divisor, j = counter
  d > n ?                        // if d is greater than n:
    j                            //   append j and stop recursion
  :                              // else:
    n % d ?                      //   if d is not a divisor of n:
      D(n, d + 1) + (            //     recursive call with n unchanged and d = d + 1
        j ?                      //     if j is not undefined:
          [,j]                   //       append a comma followed by j
        :                        //     else:
          []                     //       append nothing
      )                          //
    :                            //   else:
      D(n / d, d, -~j)           //     recursive call with n divided by d and j = j + 1

Main function:

N =>                             // N = target index in the sequence
  (F = m =>                      // m = # of times the leader has been encountered
    N ?                          // if N is not equal to 0:
      F(                         //   do a recursive call to F():
        (F[k = D(++n)] =         //     increment n; k = reduced prime factorization of n
                         -~F[k]) //     increment F[k] = # of times k has been encountered
        > m ?                    //     if the result is greater than m:
          F[N -= p != k,         //       decrement N if p is not equal to k
                         p = k]  //       update p and set m to F[p]
        :                        //     else:
          m                      //       let m unchanged
      )                          //   end of recursive call
    :                            // else:
      n                          //   stop recursion and return n
  )(n = p = 0)                   // initial call to F() with m = n = p = 0
\$\endgroup\$
1
\$\begingroup\$

Stax, 24 bytes

Ç▓Δk/‼&²Θºk∙♥╜fv╛Pg8╝j♀§

This program takes no input and theoretically produces infinite output. I say "theoretically" because the 8th element will take more than a year.

Run and debug it

The corresponding ascii representation of the same program is this.

0WYi^{|n0-m|=c:uny=!*{i^Q}Md

It keeps the last leader on the stack. Iterating over integers, if there's a distinct mode in the factor representation, and it's different than the last one, output it.

0                               push zero for a placeholder factorization
 W                              repeat the rest of the program forever
  Y                             store the last factorization in the y register
   i^                           i+1 where i is the iteration index
     {    m                     using this block, map values [1 .. i+1]
      |n0-                          get the prime exponents, and remove zeroes 
           |=                   get all modes
             c:u                copy mode array and test if there's only one
                ny=!            test if mode array is not equal to last leader
                    *           multiply; this is a logical and
                     {   }M     if true, execute this block
                      i^Q       push i+1 and print without popping
                           d    discard the top of stack
                                    if it was a leader change, this pops i+1
                                    otherwise it pops the mode array
                                at this point, the last leader is on top of 
                                the stack
\$\endgroup\$
0
\$\begingroup\$

Python 2, 145 bytes

m=i=0;f=[]
while 1:
 i+=1;a=i;d=[0]*-~i;k=2
 while~-a:x=a%k>0;k+=x;a/=x or k;d[k]+=1-x
 k=filter(abs,d);f+=k,;c=f.count
 if c(k)>c(m):print i;m=k

Try it online!

Ungolfed

m=0                    # reduced prime factorizations leader
i=0                    # current number
f=[]                   # list of reduced prime factorizations
while 1:               # Infinite loop:
  i+=1                 #   next number
  a=i                  #   a is used for the prime factorization
  d=[0]*-~i            #   this lists stores the multiplicity
  k=2                  #   current factor
  while~-a:            #   As long as a-1 != 0:
    x=a%k>0            #      x := not (k divides a)
    k+=x               #      If k does not divide a, go to the next factor
    a/=x or k          #      If k does not divide a,
                       #         divide a by 1,
                       #         else divide it by k
    d[k]+=1-x          #      add 1 to the multiplicity of k if k divides a
  k=filter(abs,d)      #   Only keep non-zero multiplicities
                       #     k is now the reduced prime factorization of i
  f+=k,                #   append k to the list of reduced prime factorizations
  c=f.count            #   c(x) := number of occurences of x in f
  if c(k)>c(m):        #   has the current reduced prime factorization
                       #    appeared more often than the leader?
    print i;m=k        #     print the current number, set new leader

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Jelly,  35  34 bytes

I feel like it's still golfable

ÆEḟ0µ€ĠL€M⁸’ߤ¹Ṗ?
®‘©Ç€F0;ITµL<³µ¿

A full program taking k and outputting a Jelly list representation of the first k leader change points.

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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