Ordenar los divisores de un número por factorización prima


23

Dada una entrada de un entero ≥ 2, genera una lista de sus divisores ordenados por los exponentes en sus factorizaciones primas, en orden ascendente, ordenando primero por el primo más grande, luego por el segundo más grande, y así sucesivamente.

Como ejemplo, tome el número entero 72, que es 2 3 3 2 . Tiene los divisores

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

Cuando se ordena en orden ascendente por los exponentes en los factores primos, con primos más grandes teniendo prioridad, esto se convierte

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

Tenga en cuenta que la lista se ordena primero por el orden del exponente de 3, y luego por el exponente de 2. También puede considerar esto como una lectura de izquierda a derecha y de arriba a abajo en la siguiente cuadrícula:

        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

Casos de prueba:

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

Como se trata de , gana el código más corto en bytes.

Respuestas:


8

05AB1E , 6 bytes

Código:

ÑÒí{€P

Explicación:

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

Utiliza la codificación CP-1252 . Pruébalo en línea! .


1
Noice: p (bien hecho)
framp

8

Jalea , 8 7 bytes

ÆDÆfU$Þ

Pruébalo en línea! Gracias a @Dennis por -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

2
ÆDÆfU$Þ(usando la nueva clasificación de Jelly), guarda un byte.
Dennis

7

Pyth, 10 bytes

+1{*Mt_DyP

Pruébelo en línea: demostración

Lamentablemente, el producto sobre una lista vacía no se define como 1 en Pyth. Esto cuesta tres bytes adicionales.

Explicación:

+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

7

Jalea , 12 10 bytes

2 bytes gracias a @ Sp3000.

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

Pruébalo en línea!

Banco de pruebas.

Æ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

Créditos a @ Sp3000 por proponer el formato de la explicación.


7

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

Sin factorización, sin clasificación. Implementación recursiva de la misma longitud:

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

5

En realidad, 19 bytes

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

Pruébalo en línea!

Explicación:

;÷#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

5

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)

Basado en la idea de @ xnor, aunque no entendí su código, así que tuve que volver a implementarlo desde cero. El algoritmo básico es que comienzas con [1] y multiplicas por [1, ..., pᵏ] para cada pᵏ en la factorización prima de n, aunque como no tengo factorización prima o producto cartesiano tengo que hacerlo Todo recursivamente. Ejemplo:

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]

Acabo de recordar cuando estabas en 10k ... ahora casi en 14k. ¡¡Seguid así!!
NiCk Newman

2

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

Esto va a ser ineficiente como diablos porque apenas resistí la tentación de usar library(primes). Crea un vector dde todos los factores primos de la entrada, calcula su frecuencia (número de ocurrencias) y luego calcula el producto cartesiano de todas las potencias posibles (desde 0 hasta la frecuencia respectiva b[i]), a las cuales prodse aplica la función. ¡Maldita sea, casos especiales de 2 y 3! De lo contrario, este es un buen escaparate del manejo del marco de datos R y las funciones vectoriales / operaciones por fila (¡e incluso la tablefunción puramente estadística !).

Por supuesto, su eficiencia se puede mejorar a un costo de 15 bytes usando r=2:ceiling(sqrt(n)), si a alguien le importa. Aquí hay una versión más agradable sin golf:

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
  }
}

2

Mathematica 150 bytes

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

2

Brachylog , 3 bytes

fḋᵒ

Pruébalo en línea!

El código se lee más o menos como el título del desafío: "los factores de la entrada, ordenados por sus descomposiciones principales". Asegurándome de que esta belleza de 3 bytes realmente pasara los casos de prueba usando solo el sentido incorporado de Brachylog de cómo ordenar las listas terminó requiriendo que copie y pegue todos esos números en el Clojure REPL, donde los elementos de la lista están separados por espacios en blanco y las comas son espacios en blanco, pero resultó que sí funciona.


2

APL (Dyalog Extended) , 17 bytes

Muchas gracias a ngn y Adám por su ayuda en el golf de estos dos programas de APL en The APL Orchard , un excelente lugar para aprender APL y obtener ayuda de APL.

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

Pruébalo en línea!

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) , SBCS de 29 bytes

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

Pruébalo en línea!

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.

1

J, 32 31 bytes

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

Toma las listas de primos y exponentes del entero de entrada, invierte cada uno y construye los divisores a partir de eso.

Uso

   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

Explicación

[:(*/@#~>:#:[: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

1

Ruby, 71 bytes

Esta respuesta se basa en la respuesta de Python 2 de xnor.

->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}

Una alternativa de la misma longitud es:

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

No golfista:

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

1

Japt , 12 9 bytes

â mk ñÔ®×

-3 bytes gracias a @Shaggy

Pruébalo en línea!


Esto debería funcionar para 9 bytes.
Shaggy

@ Shaggy Oh, sí, olvidé que las funciones simples deberían definirse de esa manera, a pesar de que solo lo sugerí para lol solo para ASCII
Quintec


0

Mathematica, 56 bytes

1##&@@@Tuples@Reverse[#^Range[0,#2]&@@@FactorInteger@#]&
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.