Tôi có bao nhiêu phân vùng?


16

Số phân vùng của một số nguyên dương được định nghĩa là số cách nó có thể được biểu thị dưới dạng tổng của các số nguyên dương. Nói cách khác, số lượng phân vùng nguyên nó có. Ví dụ: số 4có các phần sau:

[[1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2], [4]]

Do đó, nó có 5phân vùng. Đây là OEIS A000041 .


Bài tập

Cho một số nguyên dương N xác định số phân vùng của nó.

  • Tất cả các quy tắc tiêu chuẩn được áp dụng.

  • Đầu vào và đầu ra có thể được xử lý thông qua bất kỳ giá trị trung bình hợp lý.

  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.


Các trường hợp thử nghiệm

Đầu vào | Đầu ra

1 | 1
2 | 2
3 | 3
4 | 5
5 | 7
6 | 11
7 | 15
8 | 22
9 | 30
10 | 42

1
Tôi gần như tích cực đây là một bản sao ...
DJMcMayhem

@DJMcMayhem Umm, ok. Hãy cho tôi biết nếu bạn tìm thấy một bản sao. Xin lỗi, tôi mới biết tất cả những điều này!

1
@DJMcMayhem có thể câu hỏi này bạn đã hỏi vì đây là một bước ngắn từ "tạo" đến "đếm" nhưng bạn không nhất thiết phải tạo tất cả các phân vùng để đếm chúng ...
Giuseppe

1
đây là một bản dupe, NGOẠI TRỪ là một popcon (?) và đóng vì quá rộng. IMHO đây là cách tốt hơn bằng văn bản và nên được mở, trong khi cái cũ nên được mở lại và đóng lại dưới dạng dupe
Rod

2
@Rod, đó là một pop-con tồi, nhưng chuyển lý do gần gũi sang dupe sẽ không phải là một cải tiến. Yêu cầu về hiệu suất sẽ có một trở ngại trong việc đưa ra một số câu trả lời (không ai sẽ tạo ra 24061467864032622473692149727991 phân vùng 1000 trong vài phút); và việc triển khai Hardy-Ramanujan-Rademacher không được đánh gôn chính xác ... Tuy nhiên, có thể đáng để mở một cuộc thảo luận trong meta về việc phải làm gì với câu hỏi này và câu hỏi đó.
Peter Taylor

Câu trả lời:


13

Bình thường , 3 byte

l./

Hãy thử nó ở đây! hoặc Thử một bộ thử nghiệm.

Câu trả lời mất nhiều thời gian hơn để định dạng hơn là tự viết mã: P.


Làm sao?

Pyth là công cụ phù hợp cho công việc.

l. / Chương trình đầy đủ với đầu vào ẩn.

 ./ Phân vùng nguyên. Trả về tất cả các danh sách đã sắp xếp của các số nguyên dương thêm vào đầu vào.
l Chiều dài.
      Ngẫu nhiên xuất kết quả.

34

Toán học, 11 byte

PartitionsP

Giải trình

¯\_(ツ)_/¯

8

Python 2 , 85 83 byte

-2 byte nhờ @notjagan

lambda n:n<1or sum(sum(i*((n-k)%i<1)for i in range(1,n+1))*p(k)for k in range(n))/n

Hãy thử trực tuyến!

Sử dụng công thức đệ quy từ OEIS A000041 .



84 byte . ==0tương đương với <1trong trường hợp này. EDIT: Sử dụng phương pháp của notjagan
Ông Xcoder

@ Mr.Xcoder Mã ban đầu thực sự có <1thay thế ==0, nhưng mã TIO thì không.
notjagan

Ngoài ra 83 byte .
Ông Xcoder

8

Biểu tượng cảm xúc 0,5, 204 201 byte

🐋🚂🍇🐖🅰️➡🚂🍇🍊⬅🐕1🍇🍎1🍉🍮s 0🔂k⏩0🐕🍇🍦t➖🐕k🍮r t🔂i⏩1 t🍇🍊😛🚮t i 0🍇🍮➕r i🍉🍉🍮➕s✖r🅰️k🍉🍎➗s🐕🍉🍉

Hãy thử trực tuyến!

-3 byte bằng cách sử dụng "ít hơn hoặc bằng 1" thay vì "nhỏ hơn 2" vì biểu tượng cảm xúc "nhỏ hơn" có mã hóa UTF-8 khá dài. Cũng thực hiện tđóng băng để tắt tiếng cảnh báo mà không ảnh hưởng đến số byte.

Mở rộng lớp (số nguyên) bằng một phương thức có tên. Bạn có thể viết một chương trình đơn giản lấy một số từ đầu vào, gọi vào số đó và in kết quả như thế này:

🏁🍇
 🍦str🔷🔡😯🔤Please enter a number🔤
 🍊🍦num🚂str 10🍇
  😀🔡🅰️num 10
 🍉🍓🍇
  😀🔤Learn what a number is, you moron!🔤
 🍉
🍉

Phần này có thể được chơi rất nhiều bằng cách bỏ qua các thông báo và xử lý lỗi, nhưng nó không được bao gồm trong điểm số, vì vậy tôi thích hiển thị nhiều tính năng hơn của Biểu tượng cảm xúc thay vào đó, đồng thời cải thiện khả năng đọc trên đường đi.

Bị đánh cắp

🐋🚂🍇
 🐖🅰️➡🚂🍇
  🍊◀️🐕2🍇
   🍎1
  🍉
  🍮sum 0
  🔂k⏩0🐕🍇
   🍦nmk➖🐕k
   🍮sig nmk
   🔂i⏩1 nmk🍇
    🍊😛🚮nmk i 0🍇
     🍮➕sig i
    🍉
   🍉
   🍮➕sum✖sig🅰️k
  🍉
  🍎➗sum🐕
 🍉
🍉

Giải trình

Lưu ý: rất nhiều lựa chọn biểu tượng cảm xúc không có nhiều ý nghĩa trong biểu tượng cảm xúc 0,5. Đó là 0.x, sau tất cả. 0,6 sẽ khắc phục điều này.

Biểu tượng cảm xúc là ngôn ngữ lập trình hướng đối tượng bao gồm các tổng quát, giao thức, tùy chọn và bao đóng, nhưng chương trình này không sử dụng các bao đóng và tất cả các tổng quát và giao thức có thể được coi là ẩn, trong khi tùy chọn duy nhất xuất hiện trong sơ khai I / O.

Chương trình chỉ hoạt động trên một vài loại: là loại số nguyên, là loại chuỗi và là loại phạm vi. Một số booleans (👌) cũng xuất hiện, nhưng chúng chỉ được sử dụng trong điều kiện. Booleans có thể lấy giá trị hoặc, tương ứng với đúng và sai, tương ứng.

Hiện tại không có toán tử nào trong Biểu tượng cảm xúc, do đó, phép cộng và các phép toán khác thường là toán tử được triển khai dưới dạng hàm, làm cho các biểu thức sử dụng ký hiệu tiền tố một cách hiệu quả . Các nhà khai thác cũng được lên kế hoạch trong 0,6.

Trước tiên hãy giải quyết chương trình thử nghiệm.

🏁

Đây là khối, có thể được so sánh với chính từ các ngôn ngữ khác.

🍇 ... 🍉

Nho và dưa hấu khai báo khối mã trong biểu tượng cảm xúc.

🍦str🔷🔡😯🔤Please enter a number🔤

Điều này tuyên bố một tên "đóng băng" được đặt tên strvà đặt giá trị của nó thành một chuỗi mới được tạo bằng bộ khởi tạo (hàm tạo), lấy một dấu nhắc làm chuỗi và sau đó nhập một dòng từ người dùng. Tại sao sử dụng đông lạnh thay vì một biến? Nó sẽ không thay đổi, vì vậy một biến sẽ phát ra cảnh báo.

🍊🍦num🚂str 10

Hãy phá vỡ nó. 🚂str 10gọi phương thức on trên strđóng băng với đối số 10. Theo quy ước, các phương thức được đặt tên với tên của một loại chuyển đổi đối tượng thành loại đó. 10 là cơ sở để sử dụng cho chuyển đổi số nguyên. Phương pháp này trả về một tùy chọn , 🍬🚂. Tùy chọn có thể chứa một giá trị của loại cơ sở hoặc hư vô,. Khi chuỗi không chứa số, được trả về. Để sử dụng giá trị, người ta phải hủy tùy chọn bằng cách sử dụng, điều này sẽ gây ra lỗi thời gian chạy nếu giá trị là. Vì vậy, đó là một thực hành tốt để kiểm tra hư vô trước khi mở ra một tùy chọn. Trên thực tế, nó rất phổ biến đến nỗi Emojicode có một tốc ký cho điều đó. Thông thường, 🍊là "nếu".🍊🍦 variable expressioncó nghĩa là: đánh giá biểu thức. Nếu tùy chọn chứa hư vô, điều kiện ước tính là (sai). Mặt khác, một tên variableđược đóng băng được tạo ra với giá trị không được bao bọc của tùy chọn và điều kiện ước tính là 👍, (đúng). Do đó, trong sử dụng bình thường, 🍇 ... 🍉khối theo điều kiện được nhập.

😀🔡🅰️num 10

Là phương thức mà mã chính thêm vào 🚂 bằng cách sử dụng tính toán số lượng phân vùng. Điều này gọi trên phần numđông lạnh mà chúng ta đã khai báo trong điều kiện và chuyển đổi kết quả thành một chuỗi bằng cách sử dụng cơ sở 10 theo phương pháp. Sau đó, in kết quả.

🍓🍇 ... 🍉

Có nghĩa là "khác", vì vậy khối này được nhập khi người dùng không nhập đúng số.

😀🔤Learn what a number is, you moron!🔤

In chuỗi ký tự.

Bây giờ, hãy nhìn vào chương trình chính. Tôi sẽ giải thích phiên bản vô văn hóa; phiên bản chơi gôn đã loại bỏ khoảng trắng và các biến được đổi tên thành tên chữ cái duy nhất.

🐋🚂🍇 ... 🍉

Mở rộng lớp. Đây là một tính năng không thường thấy trong các ngôn ngữ lập trình. Thay vì tạo một lớp mới với là siêu lớp, sửa đổi trực tiếp.

🐖🅰️➡🚂🍇 ... 🍉

Tạo một phương thức mới có tên trả về một. Nó trả về số lượng phân vùng được tính bằng công thứca(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)

🍊⬅🐕1🍇
 🍎1
🍉

Tương tự thishoặc selftừ các ngôn ngữ khác và đề cập đến đối tượng mà phương thức được gọi. Việc thực hiện này là đệ quy, vì vậy đây là điều kiện kết thúc: nếu số phương thức được gọi trên nhỏ hơn hoặc bằng 1, trả về 1.

🍮sum 0

Tạo một biến mới sumvà đặt nó thành 0. Giả định ngầm định loại.

🔂k⏩0🐕

Lặp đi lặp lại bất cứ điều gì thực hiện giao thức, trong khi là một phạm vi nghĩa đen xảy ra để thực hiện. Một phạm vi có giá trị bắt đầu, giá trị dừng và giá trị bước, được giả sử là 1 nếu start < stophoặc -1 nếu không. Người ta cũng có thể chỉ định giá trị bước bằng cách sử dụng để tạo phạm vi bằng chữ. Giá trị bắt đầu được bao gồm, trong khi giá trị dừng là độc quyền, do đó, giá trị này tương đương với for k in range(n)hoặc Sum_{k=0..n-1}trong công thức.

🍦nmk➖🐕k

Chúng ta cần tính sigma (n - k) hoặc tổng các ước của n - kcác từ khác và đối số là cần thiết một vài lần, vì vậy điều này lưu trữ n - ktrong biến nmkđể lưu một số byte.

🍮sig nmk
🔂i⏩1 nmk

Điều này đặt sigbiến cho đối số của sigma và lặp lại trên tất cả các số từ 1 đến nmk - 1. Tôi có thể khởi tạo biến thành 0 và lặp lại trên 1..nmk nhưng thực hiện theo cách này ngắn hơn.

🍊😛🚮nmk i 0

Tính toán phần còn lại hoặc mô đun và kiểm tra sự bằng nhau, do đó điều kiện sẽ là 👍 nếu ilà một bộ chia của nmk.

🍮➕sig i

Đây là một bài tập theo cuộc gọi, tương tự như họ += -= >>=nhà điều hành trong một số ngôn ngữ kém, không có biểu tượng cảm xúc. Dòng này cũng có thể được viết là 🍮 sig ➕ sig i. Do đó, sau khi vòng lặp bên trong kết thúc, sigsẽ chứa tổng các ước của n - khoặcsigma(n - k)

🍮➕sum✖sig🅰️k

Một nhiệm vụ khác bằng cách gọi, vì vậy điều này thêm sigma(n - k) * A(k)vào tổng số, giống như trong công thức.

🍎➗sum🐕

Cuối cùng, tổng được chia cho n và thương số được trả về. Lời giải thích này có lẽ đã khiến ba lần mất nhiều thời gian như tự viết mã ...



3

Octave, 18 byte

partcnt(input(''))

Sử dụng hàm partcnt tích hợp.

Không thể hiểu đúng bằng cách sử dụng chức năng ẩn danh bằng cách sử dụng @, một số trợ giúp sẽ được đánh giá cao.


3

Võng mạc , 34 byte

.+
$*
+%1`\B
;$'¶$`,
,

%O`1+
@`.+

Hãy thử trực tuyến!

Giải trình

.+
$*

Chuyển đổi đầu vào thành unary.

+%1`\B
;$'¶$`,

Điều này sẽ tính toán tất cả 2 phân vùng n-1 của danh sách chữ số đơn. Chúng tôi thực hiện điều này bằng cách lặp lại ( +) khớp với 1ranh giới không từ đầu tiên ( ) \B, tức là vị trí giữa hai 1s) trong mỗi dòng ( %) và thay thế nó bằng ;, mọi thứ sau nó ( $'), linefeed ( ), mọi thứ ở phía trước nó ( $`) và ,. Thí dụ:

1;1,111

Trở thành

      vv
1;1,1;11
1;1,1,11
^^^^^

Trường hợp vđánh dấu kết quả $'^đánh dấu kết quả $`. Đây là một thành ngữ phổ biến để có được kết quả của hai lần thay thế khác nhau cùng một lúc (về cơ bản chúng tôi chèn cả thay thế ;,thay thế, cũng như "một nửa" còn thiếu của chuỗi để hoàn thành hai lần thay thế hoàn toàn).

Chúng tôi sẽ coi ;các phân vùng thực tế và ,giống như các trình giữ chỗ ngăn không cho \Bkhớp tiếp theo ở đó. Tiếp theo...

,

... Chúng tôi xóa những dấu phẩy đó. Điều đó cho chúng ta tất cả các phân vùng. Ví dụ cho đầu vào, 4chúng tôi nhận được:

1;1;1;1
1;1;11
1;11;1
1;111
11;1;1
11;11
111;1
1111

Chúng tôi không quan tâm đến thứ tự mặc dù:

%O`1+

Điều này sắp xếp các lần chạy của 1mỗi dòng để chúng ta có được các phân vùng không có thứ tự.

@`.+

Cuối cùng, chúng tôi đếm các @kết quả khớp ( ) duy nhất của .+, tức là có bao nhiêu dòng / phân vùng riêng biệt mà chúng tôi thu được. Tôi đã thêm @tùy chọn này từ lâu, sau đó hoàn toàn quên nó và chỉ gần đây mới khám phá lại nó. Trong trường hợp này, nó lưu một byte qua lần lặp đầu tiên với các dòng D`.


3

Python 2 , 54 53 byte

f=lambda n,k=1:1+sum(f(n-j,j)for j in range(k,n/2+1))

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Mỗi phân vùng của n có thể được biểu diễn dưới dạng một danh sách x = [x 1 ,, x m ] sao cho x 1 + + x m = n . Biểu diễn này trở nên duy nhất nếu chúng ta yêu cầu x 1 x m .

Chúng tôi xác định một hàm phụ f (n, k) đếm các phân vùng có k ràng buộc thấp hơn , tức là các danh sách x sao cho x 1 + + x m = nk ≤ x 1 ⋯ ≤ x m . Đối với đầu vào n , do đó, thách thức yêu cầu đầu ra của f (n, 1) .

Đối với các số nguyên dương nk sao cho k ≤ n , có ít nhất một phân vùng có k ràng buộc thấp hơn : danh sách đơn [n] . Nếu n = k (cụ thể, nếu n = 1 ), đây là phân vùng đủ điều kiện duy nhất . Mặt khác, nếu k> n , không có giải pháp nào cả.

Nếu k <n , chúng ta có thể đếm đệ quy các phân vùng còn lại bằng cách xây dựng chúng từ trái sang phải, như sau. Với mỗi j sao cho k ≤ j ≤ n / 2 , chúng ta có thể xây dựng các phân vùng [x 1 , ⋯, x m ] = [j, y 1 , ⋯, y m - 1 ] . Ta có x 1 + + x m = n khi và chỉ khi y 1 + ⋯ + y m - 1 = n - j . Hơn nữa, x 1 x m khi và chỉ khi j ≤ y 1 ≤ ⋯ y m - 1 .

Do đó, các phân vùng x của n bắt đầu bằng j có thể được tính là f (n - j, j) , tính các phân vùng hợp lệ y . Bằng cách yêu cầu j ≤ n / 2 , chúng tôi đảm bảo rằng j ≤ n - j , do đó có ít nhất một y . Do đó, chúng ta có thể đếm tất cả các phân vùng của n bằng cách tính tổng 1 (cho [n] ) và f (n - j, j) cho tất cả các giá trị hợp lệ của j .

Mã này là một triển khai đơn giản của hàm toán học f . Ngoài ra, nó làm cho k mặc định là 1 , do đó, f(n)tính giá trị của f (n, 1) cho đầu vào n .


Ồ wow, điều này thật phi thường! Bạn có thể thêm một lời giải thích về cách thức này hoạt động?

Tôi đã chỉnh sửa câu trả lời của mình. Nếu bất cứ điều gì chưa rõ, xin vui lòng cho tôi biết.
Dennis

3

J , 37 35 byte

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:

Hãy thử trực tuyến!

Giải trình

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:  Input: n
                                 1:  Constant 1
  ]                                  Get n
   1&(                          )    Repeat n times on x = [1]
                          \            For each prefix
                         #               Length
                      q:@                Prime factors
                 /.~&                    Group equal factors
              #.~                        Compute p+p^2+...+p^k for each group
           >:@                           Increment
                    &.q:                 Product
                           %           Divide
                            #          Length
         ]                             Get x
          *                            Times
   1   #.                              Sum
                              ,        Joim
                               ]       Get x
                                       Set this as next value of x
0{                                   Select value at index 0

Tôi chết lặng và chết lặng, tâm trí đăng một lời giải thích?
cole

1
@cole Đây là cách tiếp cận lặp lại bắt đầu bằng giải pháp cho p (0) = 1 và xây dựng phương pháp tiếp theo bằng công thức p(n) = sum(sigma(n-k) * p(k) for k = 0 to n-1) / n. Tôi sẽ thêm một lời giải thích về mã sau này khi tôi tin rằng nó không thể rút ngắn đáng kể.
dặm

2

JavaScript, 125 121 byte

n=>(z=(a,b)=>[...Array(a)].map(b))(++n**n,(_,a)=>z[F=z(n,_=>a%(a/=n,n)|0).sort().join`+`]=b+=eval(F)==n-1&!z[F],b=0)|b||1

Hãy thử trực tuyến!

Cảnh báo: độ phức tạp của thời gian và không gian là theo cấp số nhân. Hoạt động rất chậm đối với số lượng lớn.


2

Python 2 , 89 byte

-9 byte bởi Mr.Xcoder -1 byte bởi notjagan

lambda n:len(p(n))
p=lambda n,I=1:{(n,)}|{y+(x,)for x in range(I,n/2+1)for y in p(n-x,x)}

Hãy thử trực tuyến!



@ Mr.Xcoder Thậm chí không biết, tại sao tôi không sử dụng lambda D:
Dead Possum

Hehe, ¯\_(ツ)_/¯- BTW, nếu bạn muốn giữ cho nó đầy đủ chức năng, bạn sẽ không cần biến, 94 byte
Ông Xcoder

@ Mr.Xcoder Vâng .. Tôi cảm thấy rỉ sét sau một thời gian rời xa codegolf: c
Dead Possum



0

Java 8 (229 byte)

import java.util.function.*;class A{static int j=0;static BiConsumer<Integer,Integer>f=(n,m)->{if(n==0)j++;else for(int i=Math.min(m,n);i>=1;i--)A.f.accept(n-i,i);};static Function<Integer,Integer>g=n->{f.accept(n,n);return j;};}

Ung dung:

import java.util.function.*;

class A {
    static int j = 0;
    static BiConsumer<Integer, Integer> f = (n, m) -> {
        if (n == 0)
            j++;
        else
            for (int i = Math.min(m, n); i >= 1; i--)
                A.f.accept(n - i, i);
    };
    static Function<Integer, Integer> g = n -> {
        f.accept(n, n);
        return j;
    };
}

0

Thạch , 3 byte

Nguyên Œṗtử gần đây đã được thêm vào và có nghĩa là "Phân vùng nguyên".

ŒṗL

Hãy thử trực tuyến!

L - Chương trình đầy đủ.

Œṗ - Phân vùng nguyên.
  L - Chiều dài.
      - Đầu ra ngầm.


0

JavaScript ES7, 69 byte

n=>(f=(i,s)=>i?[for(c of Array(1+n))f(i-1,s,s-=i)]:c+=!s)(n,n,c=0)&&c

JavaScript ES6, 71 byte

n=>(f=(i,s)=>i?[...Array(1+n)].map(_=>f(i-1,s,s-=i)):c+=!s)(n,n,c=0)&&c

Độ phức tạp thời gian O (n ^ n), vì vậy hãy cẩn thận (xuất hiện độ trễ rõ ràng trên máy tính của tôi F(6))

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.