素因数分解による数の約数の並べ替え


23

2以上の整数の入力が与えられると、その素因数分解の指数で昇順でソートされた除数のリストを出力します。

例として、2 3 3 2の整数72を使用します。除数があります

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

素因数の指数で昇順で並べ替えると、より大きい素数が優先され、これは次のようになります。

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

リストは、最初に指数3の順序でソートされ、次に指数2でソートされることに注意してください。これは、次のグリッドを左から右、上から下へ読み取ることと考えることもできます。

        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

テストケース:

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

これはであるため、バイト単位の最短コードが優先されます。

回答:



8

ゼリー8 7 バイト

ÆDÆfU$Þ

オンラインでお試しください!-1バイトの@Dennisに感謝します。

Æ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$Þ(Jellyの新しい並べ替えを使用)、バイトを保存します。
デニス

7

Pyth、10バイト

+1{*Mt_DyP

オンラインで試す:デモンストレーション

悲しいことに、空のリスト上の製品は、Pythでは1として定義されていません。これには3バイト余分にかかります。

説明:

+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

ゼリー12 10 バイト

@ Sp3000のおかげで2バイト。

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

オンラインでお試しください!

テストスイート。

Æ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

説明の形式を思いついた@ Sp3000に感謝します。


7

Python 2、85バイト

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

因数分解、ソートなし。同じ長さの再帰的実装:

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

実際には、19バイト

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

オンラインでお試しください!

説明:

;÷#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バイト

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)

@xnorのアイデアに基づいていますが、私は彼のコードを理解していませんでしたので、ゼロから再実装する必要がありました。基本的なアルゴリズムは、[1]で始まり、nの素因数分解の各pᵏに対して[1、...、pᵏ]を掛けることです。ただし、素因数分解またはデカルト積がないため、これを行う必要がありますすべて再帰的に。例:

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]

あなたが10kであったときにちょうど覚えていた..今ではほぼ14kで。がんばり続ける!!
ニック・ニューマン

2

R、196バイト

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

私は使用する誘惑にほとんど抵抗しなかったので、これは一体として非効率になりそうlibrary(primes)です。d入力のすべての素因数のベクトルを作成し、それらの頻度(発生回数)を計算しb[i]prod関数が適用されるすべての可能なパワー(0からそれぞれの頻度)のデカルト積を計算します。ぶっちゃけ、2と3の特別なケース!それ以外の場合、これはRデータフレーム処理とベクトル関数/行ごとの操作(および純粋な統計table関数ですら)の素晴らしいショーケースです。

もちろん、r=2:ceiling(sqrt(n))誰かが気にするなら、その効率はを使用して15バイトのコストで改善できます。より良いバージョンは次のとおりです。

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バイト

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

2

Brachylog、3バイト

fḋᵒ

オンラインでお試しください!

このコードは、チャレンジのタイトルとして「多かれ少なかれ読み取ります。入力の要素は、素数の分解によってソートされています」。この3バイトの美しさは、リストを並べ替える方法のBrachylogの組み込みの感覚だけを使用して実際にテストケースに合格したことを確認するために、リスト要素が空白で区切られたClojure REPLにそれらすべての数をコピーして貼り付ける必要がありましたカンマは空白ですが、実際に機能することがわかりました。


2

APL(Dyalog Extended)、17バイト

APLを学び、APLの助けを得るのに最適なThe APL Orchardで、これらのAPLプログラムの両方をゴルフで手伝ってくれたngnとAdámに感謝します。

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

オンラインでお試しください!

アンゴルフ

∊×⍀/⌽{⊂×\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 バイトSBCS

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

オンラインでお試しください!

アンゴルフ

{∊∘.×/⌽{⊂×\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バイト

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

入力整数の素数と指数のリストを取得し、それぞれを逆にして、それから除数を作成します。

使用法

   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

説明

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

ルビー、71バイト

この回答は、xnorのPython 2の回答に基づいています。

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

同じ長さの代替手段は次のとおりです。

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

アンゴルフ:

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



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.