Classifique os divisores de um número por fatoração primária

23

Dada a entrada de um número inteiro ≥ 2, produza uma lista de seus divisores classificados pelos expoentes em suas fatorações primárias, em ordem crescente, ordenando primeiro pelo maior primo, depois pelo segundo maior e assim por diante.

Como exemplo, considere o número inteiro 72, que é 2 3 3 2 . Tem os 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

Quando ordenados em ordem crescente pelos expoentes nos fatores primos, com primos maiores tendo prioridade, isso se torna

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

Observe que a lista é classificada primeiro pela ordem do expoente de 3 e depois pelo expoente de 2. Você também pode pensar nisso como lendo da esquerda para a direita e de cima para baixo na grade a seguir:

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

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 esse é o , o código mais curto em bytes vence.

Maçaneta da porta
fonte

Respostas:

8

05AB1E , 6 bytes

Código:

ÑÒí{€P

Explicação:

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

Usa a codificação CP-1252 . Experimente online! .

Adnan
fonte
1
Noice: p (bem feito) #
framp 28/07
8

Geléia , 8 7 bytes

ÆDÆfU$Þ

Experimente online! Obrigado 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
Sp3000
fonte
2
ÆDÆfU$Þ(usando a nova classificação de Jelly), salva um byte.
Dennis
7

Pitão, 10 bytes

+1{*Mt_DyP

Experimente online: Demonstração

Infelizmente, o produto em uma lista vazia não está definido como 1 em Pyth. Isso custa três bytes extras.

Explicação:

+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
Jakube
fonte
7

Gelatina , 12 10 bytes

2 bytes graças a @ Sp3000.

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

Experimente online!

Suíte de teste.

Æ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 ao @ Sp3000 por apresentar o formato da explicação.

Freira Furada
fonte
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

Sem fatoração, sem classificação. Implementação recursiva do mesmo comprimento:

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:]]
xnor
fonte
5

Na verdade, 19 bytes

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

Experimente online!

Explicação:

;÷#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
Mego
fonte
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)

Com base na idéia do @ xnor, embora eu não tenha entendido o código dele, tive que reimplementá-lo do zero. O algoritmo básico é que você começa com [1] e multiplica por [1, ..., p] para cada p na fatoração primária de n, embora, como eu não possua fatoração primária ou produto cartesiano, eu tenho que fazê-lo tudo recursivamente. Exemplo:

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]
Neil
fonte
Acabei de lembrar quando você estava em 10k. Agora quase em 14k. Mantem!!
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)}

Isso vai ser ineficiente pra caramba, porque quase não resisti à tentação de usar library(primes). Ele cria um vetor dde todos os fatores primos da entrada, calcula sua frequência (número de ocorrências) e calcula o produto cartesiano de todas as potências possíveis (de 0 à respectiva frequência b[i]), às quais a prodfunção é aplicada. Dang-lo, casos especiais de 2 e 3! Caso contrário, essa é uma boa demonstração do manuseio do quadro de dados R e das funções vetoriais / operações por linha (e até a tablefunção puramente estatística !).

Obviamente, sua eficiência pode ser melhorada ao custo de 15 bytes r=2:ceiling(sqrt(n)), se alguém se importar. Aqui está uma versão melhor e não-destruída:

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
  }
}
Andreï Kostyrka
fonte
2

Mathematica 150 bytes

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

Braquilog , 3 bytes

fḋᵒ

Experimente online!

O código lê mais ou menos exatamente como o título do desafio: "os fatores da entrada, classificados por suas decomposições primárias". Garantir que essa beleza de 3 bytes realmente passasse nos casos de teste usando apenas o senso interno de Brachylog de como classificar listas acabou exigindo que eu copiasse e cole todos esses números no Clojure REPL, onde os elementos da lista são separados por espaços em branco e vírgulas são espaços em branco, mas acabou que realmente funciona.

String não relacionada
fonte
2

APL (Dyalog Extended) , 17 bytes

Muito obrigado a ngn e Adám por sua ajuda no golfe desses dois programas da APL no The APL Orchard , um ótimo lugar para aprender APL e obter ajuda da APL.

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

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

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

Experimente 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.
Sherlock9
fonte
1

J, 32 31 bytes

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

Pega as listas de números primos e expoentes do número inteiro de entrada, inverte cada um e constrói os divisores a partir disso.

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

Explicação

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

Ruby, 71 bytes

Esta resposta é baseada na resposta Python 2 do 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}

Uma alternativa do mesmo comprimento é:

->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
Sherlock9
fonte
1

Japonês , 12 9 bytes

â mk ñÔ®×

-3 bytes graças a @Shaggy

Experimente online!

Quintec
fonte
Isso deve funcionar para 9 bytes.
Shaggy
@ Shaggy Ah, sim, esqueci que funções simples devem ser definidas dessa maneira, mesmo que eu apenas tenha sugerido isso apenas para lol ASCII
Quintec 27/02
0

Mathematica, 56 bytes

1##&@@@Tuples@Reverse[#^Range[0,#2]&@@@FactorInteger@#]&
alefalpha
fonte