23
\$\begingroup\$

Given an input of an integer ≥ 2, output a list of its divisors sorted by the exponents in their prime factorizations, in ascending order, ordering first by the largest prime, then by the second largest, and so on.

As an example, take the integer 72, which is 2332. It has the divisors

1     3^0 · 2^0
2     3^0 · 2^1
3     3^1 · 2^0
4     3^0 · 2^2
6     3^1 · 2^1
8     3^0 · 2^3
9     3^2 · 2^0
12    3^1 · 2^2
18    3^2 · 2^1
24    3^1 · 2^3
36    3^2 · 2^2
72    3^2 · 2^3

When sorted in ascending order by the exponents on the prime factors, with larger primes taking priority, this becomes

1     3^0 · 2^0
2     3^0 · 2^1
4     3^0 · 2^2
8     3^0 · 2^3
3     3^1 · 2^0
6     3^1 · 2^1
12    3^1 · 2^2
24    3^1 · 2^3
9     3^2 · 2^0
18    3^2 · 2^1
36    3^2 · 2^2
72    3^2 · 2^3

Note that the list is sorted first by the order of the exponent of 3, and then by the exponent of 2. You can also think of this as reading from left to right and top to bottom across the following grid:

        2^0  2^1  2^2  2^3

3^0     1    2    4    8
3^1     3    6    12   24
3^2     9    18   36   72

Test cases:

2 => 1 2
72 => 1 2 4 8 3 6 12 24 9 18 36 72
101 => 1 101
360 => 1 2 4 8 3 6 12 24 9 18 36 72 5 10 20 40 15 30 60 120 45 90 180 360
3780 => 1 2 4 3 6 12 9 18 36 27 54 108 5 10 20 15 30 60 45 90 180 135 270 540 7 14 28 21 42 84 63 126 252 189 378 756 35 70 140 105 210 420 315 630 1260 945 1890 3780
30030 => 1 2 3 6 5 10 15 30 7 14 21 42 35 70 105 210 11 22 33 66 55 110 165 330 77 154 231 462 385 770 1155 2310 13 26 39 78 65 130 195 390 91 182 273 546 455 910 1365 2730 143 286 429 858 715 1430 2145 4290 1001 2002 3003 6006 5005 10010 15015 30030
65536 => 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536
74088 => 1 2 4 8 3 6 12 24 9 18 36 72 27 54 108 216 7 14 28 56 21 42 84 168 63 126 252 504 189 378 756 1512 49 98 196 392 147 294 588 1176 441 882 1764 3528 1323 2646 5292 10584 343 686 1372 2744 1029 2058 4116 8232 3087 6174 12348 24696 9261 18522 37044 74088

Since this is , the shortest code in bytes wins.

\$\endgroup\$

16 Answers 16

8
\$\begingroup\$

05AB1E, 6 bytes

Code:

ÑÒí{€P

Explanation:

Ñ       # Get the divisors of input.
 Ò      # Factorize each.
  í     # Reverse each.
   {    # Sort the array.
    €P  # Product each.

Uses the CP-1252 encoding. Try it online!.

\$\endgroup\$
  • 1
    \$\begingroup\$ Noice:p (well done) \$\endgroup\$ – framp Jul 28 '16 at 13:55
8
\$\begingroup\$

Jelly, 8 7 bytes

ÆDÆfU$Þ

Try it online! Thanks to @Dennis for -1 byte.

ÆD         Array of divisors, e.g. 24 -> [1, 2, 4, 8, 3, 6, 12, 24]
      Þ    Sort by...
     $       Combine previous two links...
  Æf           Factorise each, e.g. ['', [2], [3], [2, 2], [2, 3], [2, 2, 2],
                   [2, 2, 3], [2, 2, 2, 3]]
    U          Upend/reverse each sublist
\$\endgroup\$
  • 2
    \$\begingroup\$ ÆDÆfU$Þ (using Jelly's new sort-by), saves a byte. \$\endgroup\$ – Dennis Jul 27 '16 at 11:03
7
\$\begingroup\$

Pyth, 10 bytes

+1{*Mt_DyP

Try it online: Demonstration

Sadly the product over an empty list is not defined as 1 in Pyth. This costs three extra bytes.

Explanation:

+1{*Mt_DyPQ   implicit Q (=input number) at the end
         PQ   prime factorization of input
        y     powerset
      _D      order by reversed subsets
     t        remove the empy subset
   *M         compute the product of each subsets
  {           remove duplicates
+1            prepend 1
\$\endgroup\$
7
\$\begingroup\$

Jelly, 12 10 bytes

2 bytes thanks to @Sp3000.

ÆE‘ḶUṚŒpUṚÆẸ
ÆEU‘ḶŒpUÆẸ

Try it online!

Test suite.

ÆE            Array of exponents, e.g. 24 -> [3, 1] since 24 = 2^3*3^1
  U           Upend/reverse, e.g. [1, 3]
   ‘Ḷ         Range of each, from 0, e.g. [[0, 1], [0, 1, 2, 3]]
     Œp       Cartesian product, e.g. [[0, 0], [0, 1], ..., [1, 3]]
       U      Upend, reversing the innermost lists
        ÆẸ    Inverse of ÆE, converting exponents back into a number

Credits to @Sp3000 for coming up with the format of the explanation.

\$\endgroup\$
7
\$\begingroup\$

Python 2, 85 bytes

n=input()
p,=L=[1]
while~-n:
 l=L;p+=1
 while n%p<1:L=l+[x*p for x in L];n/=p
print L

No factorization, no sorting. Same-length recursive implementation:

f=lambda n,p=2:1/n*[1]or n%p and f(n,p+1)or[x*c for x in f(n/p)for c in[1,p][x%p<1:]]
\$\endgroup\$
5
\$\begingroup\$

Actually, 19 bytes

;÷#o♂w♂RS`"iⁿ"£Mπ`M

Try it online!

Explanation:

;÷#o♂w♂RS`"iⁿ"£Mπ`M
;                    duplicate input
 ÷                   divisors
  #o                 include input in divisors list (note to self: fix this bug)
    ♂w               factor each integer into a list of [prime, exponent] pairs
      ♂R             reverse each list, so that the largest prime comes first
        S            sort the list
         `"iⁿ"£Mπ`M  for each factorization:
          "iⁿ"£M       for each [prime, exponent] pair:
           iⁿ            push prime**exponent
                π      product
\$\endgroup\$
5
\$\begingroup\$

JavaScript, 78 bytes

f=(n,p=2,a=[1],b=a)=>n<2?a:n%p?f(n,p+1,a):f(n/p,p,a.concat(b=b.map(m=>m*p)),b)

Based on @xnor's idea, although I didn't understand his code so I had to reimplement it from scratch. The basic algorithm is that you start with [1] and multiply by [1,...,pᵏ] for each pᵏ in the prime factorisation of n, although as I don't have prime factorisation or cartesian product I have to do it all recursively. Example:

n=72 p=2 a=[1] b=[1]
n=36 p=2 a=[1,2] b=[2]
n=18 p=2 a=[1,2,4] b=[4]
 n=9 p=2 a=[1,2,4,8] b=[8]
 n=9 p=3 a=[1,2,4,8] b=[1,2,4,8]
 n=3 p=3 a=[1,2,4,8,3,6,12,24] b=[3,6,12,24]
 n=1 p=3 a=[1,2,4,8,3,6,12,24,9,18,36,72] b=[9,18,36,72]
\$\endgroup\$
  • \$\begingroup\$ Just remembered when you were at 10k.. now almost at 14k. Keep it up!! \$\endgroup\$ – NiCk Newman Jul 28 '16 at 17:51
2
\$\begingroup\$

R, 196 bytes

n=scan()
if(n<4)c(1,n)else{
r=2:n
d=NULL
while(n>1){i=r[min(which(n%%r==0))];d=c(d,i);n=n/i}
m=unique(d)
b=table(d)
l=list()
for(i in 1:length(m))l[[i]]=m[i]^(0:b[i])
apply(expand.grid(l),1,prod)}

This is going to be inefficient as heck because I hardly resisted the temptation of using library(primes). It creates a vector d of all prime factors of the input, computes their frequency (number of occurreces), and then computes the cartesian product of all possible powers (from 0 to the respective frequency b[i]), to which the prod function is applied. Dang it, special cases of 2 and 3! Otherwise, this is a nice showcase of R dataframe handling and vector functions / by-row operations (and even the purely statistical table function!).

Of course, its efficiency can be improved at the cost of 15 bytes using r=2:ceiling(sqrt(n)), if someone cares. Here is a nicer ungolfed version:

factorise <- function(n){
  if (n<4) c(1,n) else { # Now that all special cases have been handled
    r=2:ceiling(sqrt(n)) # We check all divisors smaller than the square root
    d=NULL # Initiate the variable for divisors
    while (n>1) {
      i=r[min(which(n%%r==0))] # Check the first divisor with a zero remainder
      d=c(d,i) # Append it to the list of divisors
      n=n/i   # Divide by it and check again
    }
    m=unique(d) # Get unique divisors, and they are already sorted
    b=table(d) # Count their frequencies
    l=list() # Initiate a list of all possible powers of unique factors
    for(i in 1:length(m)) l[[i]]=m[i]^(0:b[i]) # Calculate powers
    apply(expand.grid(l),1,prod) # Make a cartesian dataframe and row-multiply
  }
}
\$\endgroup\$
2
\$\begingroup\$

Mathematica 150 bytes

f[t_]:=Thread@{#,IntegerExponent[t,#]&/@#}&@Prime@Range@PrimePi@Max@FactorInteger[t][[All,1]];Times@@@(#^#2&@@@#&/@Sort[Reverse/@(f@#&/@Divisors@#)])&
\$\endgroup\$
2
\$\begingroup\$

Brachylog, 3 bytes

fḋᵒ

Try it online!

The code reads more or less just as the title of the challenge: "the factors of the input, sorted by their prime decompositions". Making sure that this 3-byte beauty actually passed the test cases using only Brachylog's built-in sense of how to sort lists ended up requiring me to copy and paste all those many numbers into the Clojure REPL, where list elements are separated by whitespace and commas are whitespace, but it turned out that it does indeed work.

\$\endgroup\$
2
+100
\$\begingroup\$

APL (Dyalog Extended), 17 bytes

Many thanks to ngn and Adám for their help in golfing both of these APL programs in The APL Orchard, a great place to learn APL and get APL help.

∊×⍀/⌽{⊂×\1,⍵}⌸⍨⍭⎕

Try it online!

Ungolfing

∊×⍀/⌽{⊂×\1,⍵}⌸⍨⍭⎕

                ⎕  Gets evaluated input from stdin.
               ⍭   Gives us a list of the prime factors of our input.
                   Example for 720: 2 2 2 2 3 3 5
     {      }⌸⍨    ⌸ groups our prime factors by the keys in the left argument,
                   and ⍨ passes the prime factors as both arguments,
                   grouping all the identical primes together
                   before running a {} dfn on them
      ⊂×\1,⍵       We append 1 to each group, get a list of powers of each prime,
                   and enclose the groups to remove 0s from uneven rows.
    ⌽             This reverses the prime power groups.
 ×⍀/              This multiplies all the powers together into
                   a matrix of the divisors of our input.
                   (Same as ∘.×/ in Dyalog Unicode)
∊                  And this turns the matrix into 
                   a list of divisors sorted by prime factorization.
                   We print implicitly, and we're done.

APL (Dyalog Unicode), 29 bytesSBCS

{∊∘.×/⌽{⊂×\1,⍵}⌸⍨¯2÷/∪∧\⍵∨⍳⍵}

Try it online!

Ungolfing

{∊∘.×/⌽{⊂×\1,⍵}⌸⍨¯2÷/∪∧\⍵∨⍳⍵}

{                           }  A dfn, a function in brackets.
                        ⍵∨⍳⍵   We take the GCD of our input with 
                               all the numbers in range(1, input).
                     ∪∧\       This returns all the unique LCMs of
                               every prefix of our list of GCDs.
                               Example for 72: 1 2 6 12 24 72.
                 ¯2÷/          We divide pairwise (and in reverse)
                               by using a filter window of negative two (¯2).
                               Example for 72: 2 3 2 2 3, our prime factors.
       {      }⌸⍨              ⌸ groups our prime factors by the keys in the left argument,
                               and ⍨ passes the prime factors as both arguments,
                               grouping all the identical primes together
                               before running a {} dfn on them
           1,⍵                 We append 1 to each group.
        ⊂×\                    Then we get a list of powers of each prime,
                               and enclose the groups to remove 0s from uneven rows.
      ⌽                        This reverses the prime power groups.
  ∘.×/                         This multiplies all the powers together into 
                               a matrix of the divisors of our input.
 ∊                             And this turns the matrix into a list of divisors
                               sorted by prime factorization.
                               We return implicitly, and we're done.
\$\endgroup\$
1
\$\begingroup\$

J, 32 31 bytes

[:(*/@#~>:#:[:i.[:*/>:)&|./2&p:

Grabs the lists of primes and exponents of the input integer, reverse each, and build up the divisors from that.

Usage

   f =: [:(*/@#~>:#:[:i.[:*/>:)&|./2&p:
   f 2
1 2
   f 72
1 2 4 8 3 6 12 24 9 18 36 72
   f 101
1 101

Explanation

[:(*/@#~>:#:[:i.[:*/>:)&|./2&p:  Input: n
                           2&p:  Factor n as a list where the first row are the primes
                                 and the second are their exponents
[:                     &|./      Reverse each list
                    >:           Increment each exponent by 1
                [:*/             Reduce it using multiplication
            [:i.                 Construct a range from 0 to that product exclusive
        >:                       The list of each exponent incremented
          #:                     Reduce each number in the previous range as a mixed base
                                 using the incremented exponents
      #~                         For each mixed base value in that range, copy from
                                 the list of primes that many times
   */@                           Reduce the copied primes using multiplication
                                 Return this list of products as the result
\$\endgroup\$
1
\$\begingroup\$

Ruby, 71 bytes

This answer is based on xnor's Python 2 answer.

->n{a,=t=[1];(s=t;a+=1;(t=s+t.map{|z|z*a};n/=a)while n%a<1)while n>1;t}

A same-length alternative is:

->n{a,=t=[1];(a+=1;(t+=t.map{|z|z*a};n/=a)while n%a<1)while n>1;t.uniq}

Ungolfing:

def f(num)
  factor = 1
  list = [1]
  while num != 1
    s = list
    factor += 1
    while num % factor == 0
      list = s + list.map{|z| z*factor}
      num /= factor
    end
  end
  return list
end

def g(num)
  factor = 1
  list = [1]
  while num != 1
    factor += 1
    while num % factor == 0
      list += list.map{|z| z*factor}
      num /= factor
    end
  end
  return list.uniq
end
\$\endgroup\$
1
\$\begingroup\$

Japt, 12 9 bytes

â mk ñÔ®×

-3 bytes thanks to @Shaggy

Try it online!

\$\endgroup\$
  • \$\begingroup\$ This should work for 9 bytes. \$\endgroup\$ – Shaggy Feb 27 at 14:25
  • \$\begingroup\$ @Shaggy Oh yeah, forgot simple functions should be defined that way, even though I just suggested it for ASCII-only lol \$\endgroup\$ – Quintec Feb 27 at 14:38
1
\$\begingroup\$

Japt, 7 bytes

â ñ_k w

Run it online

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

Mathematica, 56 bytes

1##&@@@Tuples@Reverse[#^Range[0,#2]&@@@FactorInteger@#]&
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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