Các yếu tố từng phần của một số nguyên dương


23

Một bộ sưu tập các số nguyên dương d_1 d_2 ... d_klà một phân tích nhân tử của một số nguyên dương nnếu

d_1 * d_2 * ... * d_k = n

Mỗi số nguyên dương có một thừa số nguyên tố duy nhất , nhưng nói chung chúng cũng có các thừa số trong đó một số thuật ngữ là hợp số. Ví dụ

12 = 6 * 2 = 4 * 3 = 3 * 2 * 2

Viết chương trình, hàm, động từ hoặc tương tự, lấy đầu vào là một số nguyên dương duy nhất và trả về hoặc in một danh sách đầy đủ các yếu tố riêng biệt của nó. Các yếu tố có thể được tạo ra theo bất kỳ thứ tự nào, và các điều khoản của chúng có thể theo bất kỳ thứ tự nào, nhưng không có hai yếu tố nào là hoán vị lẫn nhau. Các yếu tố có thể không bao gồm 1hai trường hợp ngoại lệ: đối với đầu vào, nbạn có thể đưa ra hệ số n*1thay vì n; và đối với đầu vào, 1bạn có thể đưa ra hệ số 1thay vì danh sách trống.

Bạn có thể giả sử rằng đầu vào sẽ nằm trong phạm vi của số nguyên 32 bit đã ký. Nếu đầu ra là một chuỗi, cần có sự phân biệt rõ ràng giữa việc phân định số trong một yếu tố và phân định các yếu tố, nhưng không cần thiết (ví dụ) cho các yếu tố được nối với một *.

Mã của bạn sẽ có khả năng xử lý bất kỳ đầu vào hợp lệ nào trong vòng 10 phút trên một máy tính để bàn hợp lý.

Ví dụ

1                  [[]]
                or [[1]]
                or [[1 1]]

7                  [[7]]
                or [[7 1]]
                or [[1 7]]

12                 [[12] [6 2] [4 3] [2 3 2]]
                or variants

16                 [[2 2 2 2] [2 2 4] [2 8] [4 4] [16]]
                or variants

901800900          a list of 198091 factorisations

1338557220         a list of 246218 factorisations

Bạn có thể đăng danh sách các yếu tố 9018009001338557220nơi nào đó chúng ta có thể kiểm tra chúng không? Mã của tôi lần lượt cho tôi 2048 và 1024 nhân tố cho những con số đó và tôi không chắc tại sao.
Sherlock9

@ Sherlock9, sẽ làm điều đó khi tôi về nhà. Những gì tôi có thể làm với một trình tạo trực tuyến là cung cấp cho bạn một đầu ra hợp lệ cho 5336100 .
Peter Taylor

3
Điều này nhắc nhở tôi về một thách thức ProjectEuler (tiếc là tôi không nhớ cái nào). Nhưng ở đó bạn phải đếm số lượng nhân tố thay vì liệt kê chúng.
flawr

OEIS liên quan: A001055
Sherlock9

Câu trả lời:


12

Haskell, 56 byte

_!1=[[]]
i!n=[j:f|j<-[i..n],mod n j<1,f<-j!div n j]
(2!)

(2!)(1338557220::Int)in trong năm phút trên máy tính xách tay của tôi, khi được biên dịch với ghc -O3.

Haskell, 62 byte, nhưng nhanh hơn nhiều

i!n|i*i>n=[[n]]|0<1=[i:f|mod n i<1,f<-i!div n i]++(i+1)!n
(2!)

(2!)(1338557220::Int)in trong một phần tư giây trên máy tính xách tay của tôi, khi được biên dịch với ghc -O3.


Làm thế nào để tôi kiểm tra điều này? ghccho tôi Parse error: naked expression at top levelghcicho tôiparse error on input `='
Peter Taylor

@PeterTaylor Thay thế chức năng (2!)bằng chương trình main = print ((2!) (1338557220::Int)), biên dịch ghc -O3 factor.hsvà chạy với ./factor.
Anders Kaseorg

7

Bình thường, 29 byte

Msam+Ldgd/Hdf!%HT>S@H2tG]]Hg2

M                                def g(G, H):
                   @H2             square root of H
                  S                1-indexed range up to floor
                 >    tG           all but first G − 1 elements
            f                      filter for elements T such that:
              %HT                    H mod T
             !                       is false (0)
   m                               map for elements d:
       gd/Hd                         g(d, H/d)
    +Ld                              prepend d to each element
  a                     ]]H        append [[H]]
 s                                 concatenate
                           g2Q   print g(2, input)

Dùng thử trực tuyến

Chạy trong hai mươi giây cho 1338557220máy tính xách tay của tôi.


@PeterTaylor Cách thông thường: pyth factor.pyth(hoặc pyth -c 'Msam+Ldgd/Hdf!%HT>S@H2tG]]Hg2'), cung cấp 16trên stdin. Hãy chắc chắn rằng bạn đang sử dụng phiên bản hiện tại của Pyth; ngầm Qđã được thêm vào tháng ba. Tôi không thể tưởng tượng làm thế nào bạn có thể được chia cho số 0, mặc dù.
Anders Kaseorg

Arrrrgh. Tôi đã sử dụng "thay vì ', và bash đang mở rộng !%sang thứ khác.
Peter Taylor

6

Python , 252 313 312 311 145 141 137 135 103 84 83 byte

Điều này phần lớn dựa trên câu trả lời Pyth của Anders Kaseorg . Bất kỳ đề nghị chơi golf đều được chào đón. Hãy thử trực tuyến!

Chỉnh sửa: 19 byte được chơi golf nhờ Dennis. Đã sửa lỗi chính tả trong mã và thêm liên kết TIO.

g=lambda n,m=2:[[n]]+[j+[d]for d in range(m,int(n**.5)+1)if n%d<1for j in g(n/d,d)]

Ung dung:

def g(n, m=2):
    a = [[n]]
    s = int(n**.5) + 1
    for d in range(m, s):
        if n%d == 0:
            for j in g(n/d, d):
                a.append([d]+j)
    return a

1
**.5được thoát khỏi nhập khẩu.
Dennis

4

JavaScript (ES6), 83 byte

f=(n,a=[],m=2,i=m)=>{for(;i*i<=n;i++)n%i<1&&f(n/i,[...a,i],i);console.log(...a,n)}

Chỉ mượn thủ thuật căn bậc hai của @ AndersKaseorg vì cuối cùng nó đã tiết kiệm cho tôi byte tổng thể. In 1cho một đầu vào 1, nếu không thì không in 1.


1

Ruby 1.9+, 87 89 87 byte

Câu trả lời này dựa trên câu trả lời Pyth của Anders Kaseorg . Mã này chỉ hoạt động cho các phiên bản sau Ruby 1.9, vì lambdas cứng nhắc ->chỉ được giới thiệu trong 1.9. Bất kỳ đề nghị chơi golf đều được chào đón.

g=->n,m=2{(m..Math.sqrt(n)).select{|i|n%i<1}.flat_map{|d|g[n/d,d].map{|j|[d]+j}}+[[n]]}

Ung dung:

def g(n, m=2)
  a = [[n]]
  s = (m..Math.sqrt(n))
  t = s.select{|i|n%i<1}
  t.each do |d|
    g[n/d,d].each do |j|
      a.push([d]+j)
    end
  end
  return a
end

Điều này có yêu cầu một phiên bản cụ thể của Ruby không? Với 1.8.7, tôi nhận được khiếu nại về g[n/d,d]:wrong number of arguments (0 for 1)
Peter Taylor

Rõ ràng lambdas đâm ->đã được giới thiệu trong Ruby 1.9. Tôi sẽ chỉnh sửa câu trả lời để hiển thị số phiên bản được yêu cầu.
Sherlock9

Được rồi cảm ơn. Tôi vẫn tò mò về g[n/d,d]. g(n/d,d)tương thích ngược hơn.
Peter Taylor

1
Ah, nói chung f[n]là bắt buộc phải gọi lambdas stabby và Ruby lambdas nói chung. f(n)f ncác cuộc gọi yêu cầu defend. Thêm thông tin ở đâyđây
Sherlock9

1

J, 52 byte

[:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:

Không hiệu quả như có thể vì một số yếu tố có thể được lặp lại và việc vượt qua cuối cùng phải được thực hiện sau khi sắp xếp từng yếu tố và sau đó sao chép lại.

Hãy thử trực tuyến!(Nhưng cố gắng giữ các giá trị đầu vào nhỏ).

Trên máy tính để bàn của tôi, thời gian là

   f =: [:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:
   timex 'r =: f 1338557220'
3.14172
   # r
246218
   timex 'r =: f 901800900'
16.3849
   # r
198091

Giải trình

Phương pháp này dựa vào việc tạo tất cả các phân vùng đã đặt cho các thừa số nguyên tố của số nguyên đầu vào n . Hiệu suất là tốt nhất khi n không có hình vuông, nếu không các yếu tố trùng lặp sẽ được tạo.

[:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:  Input: integer n
                                                  }:  Curtail, forms an empty array
                       q:                             Prime factorization
                     #@                               Length, C = count prime factors
                         _&(                     )    Repeat that many times on x = []
                                 (            )"1       For each row
                                            ~.            Unique
                                         #\@              Enumerate starting at 1
                                       0,                 Prepend 0
                                  ,~"{~                   Append each of those to a
                                                          copy of the row
                               <@                         Box it
                            ;&]                         Set x as the raze of those boxes
                                                      These are now the restricted growth
                                                      strings of order C
    q:                                                Prime factorization
            (    )"$~                                 For each RGS
               /.                                       Partition it
             */                                         Get the product of each block
        /:~@                                            Sort it
      <@                                                Box it
[:~.                                                  Deduplicate
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.