Trier les diviseurs d'un nombre par décomposition en facteurs premiers


23

Étant donné une entrée d'un entier ≥ 2, sortez une liste de ses diviseurs triés par les exposants dans leurs factorisations principales, dans l'ordre croissant, triant d'abord par le plus grand premier, puis par le deuxième plus grand, et ainsi de suite.

Par exemple, prenons l'entier 72, qui est 2 3 3 2 . Il a les diviseurs

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

Lorsque trié par ordre croissant par les exposants sur les facteurs premiers, avec des nombres premiers plus importants ayant la priorité, cela devient

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

Notez que la liste est triée d'abord par l'ordre de l'exposant de 3, puis par l'exposant de 2. Vous pouvez également considérer cela comme une lecture de gauche à droite et de haut en bas sur la grille suivante:

        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

Cas de test:

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

Puisqu'il s'agit de , le code le plus court en octets l'emporte.

Réponses:


8

05AB1E , 6 octets

Code:

ÑÒí{€P

Explication:

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

Utilise l' encodage CP-1252 . Essayez-le en ligne! .


1
Noice: p (bien fait)
framp

8

Gelée , 8 7 octets

ÆDÆfU$Þ

Essayez-le en ligne! Merci à @Dennis pour -1 octet.

Æ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$Þ(en utilisant le nouveau tri de Jelly), enregistre un octet.
Dennis

7

Pyth, 10 octets

+1{*Mt_DyP

Essayez-le en ligne: Démonstration

Malheureusement, le produit sur une liste vide n'est pas défini comme 1 en Pyth. Cela coûte trois octets supplémentaires.

Explication:

+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

Gelée , 12 10 octets

2 octets grâce à @ Sp3000.

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

Essayez-le en ligne!

Suite de tests.

Æ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édits à @ Sp3000 pour avoir trouvé le format de l'explication.


7

Python 2, 85 octets

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

Pas de factorisation, pas de tri. Implémentation récursive de même longueur:

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 fait, 19 octets

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

Essayez-le en ligne!

Explication:

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

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)

Basé sur l'idée de @ xnor, même si je ne comprenais pas son code, j'ai donc dû le réimplémenter à partir de zéro. L'algorithme de base est que vous commencez par [1] et que vous multipliez par [1, ..., pᵏ] pour chaque pᵏ dans la factorisation principale de n, bien que comme je n'ai pas de factorisation principale ou de produit cartésien, je dois le faire tous récursivement. Exemple:

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]

Je me souviens juste quand tu étais à 10k .. maintenant presque à 14k. Continuez!!
NiCk Newman

2

R, 196 octets

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

Cela va être inefficace car je n'ai guère résisté à la tentation d'utiliser library(primes). Il crée un vecteur dde tous les facteurs premiers de l'entrée, calcule leur fréquence (nombre d'occurrences), puis calcule le produit cartésien de toutes les puissances possibles (de 0 à la fréquence respective b[i]), auquel la prodfonction est appliquée. Dang it, cas particuliers de 2 et 3! Sinon, c'est une belle vitrine de la gestion des trames de données R et des fonctions vectorielles / opérations par ligne (et même la tablefonction purement statistique !).

Bien sûr, son efficacité peut être améliorée au prix de 15 octets en utilisant r=2:ceiling(sqrt(n)), si quelqu'un s'en soucie. Voici une version non golfée plus agréable:

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 octets

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

2

Brachylog , 3 octets

fḋᵒ

Essayez-le en ligne!

Le code se lit plus ou moins comme le titre du défi: "les facteurs de l'entrée, triés par leurs décompositions premières". Faire en sorte que cette beauté de 3 octets réussisse réellement les cas de test en utilisant uniquement le sens intégré de Brachylog sur la façon de trier les listes a fini par m'obliger à copier et coller tous ces nombreux nombres dans le Clojure REPL, où les éléments de liste sont séparés par des espaces et les virgules sont des espaces, mais il s'est avéré que cela fonctionne.


2

APL (Dyalog Extended) , 17 octets

Un grand merci à ngn et Adám pour leur aide dans le golf de ces deux programmes APL dans The APL Orchard , un excellent endroit pour apprendre l'APL et obtenir de l'aide APL.

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

Essayez-le en ligne!

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 octets SBCS

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

Essayez-le en ligne!

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 octets

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

Récupère les listes de nombres premiers et d'exposants de l'entier d'entrée, inverse chacune et crée les diviseurs à partir de cela.

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

Explication

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

Rubis, 71 octets

Cette réponse est basée sur la réponse 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}

Une alternative de même longueur est:

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

1

Japt , 12 9 octets

â mk ñÔ®×

-3 octets grâce à @Shaggy

Essayez-le en ligne!


Cela devrait fonctionner pour 9 octets.
Shaggy

@Shaggy Oh oui, les fonctions simples oubliées devraient être définies de cette façon, même si je viens de le suggérer pour lol ASCII uniquement
Quintec


0

Mathematica, 56 octets

1##&@@@Tuples@Reverse[#^Range[0,#2]&@@@FactorInteger@#]&
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.