Đếm cây


11

Một cây là một kết nối, đồ thị vô hướng không có chu kỳ. Nhiệm vụ của bạn là đếm xem có bao nhiêu cây riêng biệt với một số đỉnh nhất định.

Hai cây được coi là khác biệt nếu chúng không phải là đẳng cấu . Hai đồ thị là đẳng cấu nếu các đỉnh tương ứng của chúng có thể được ghép nối theo cách sao cho có một cạnh giữa hai đỉnh trong một đồ thị khi và chỉ khi có một cạnh giữa các đỉnh được ghép với các đỉnh đó trong đồ thị khác. Để biết mô tả đầy đủ hơn, xem liên kết ở trên.

Để xem tất cả các cây khác nhau có kích thước từ 1 đến 6 trông như thế nào, hãy xem tại đây .

Sê-ri bạn đang cố gắng xuất là A000055 tại OEIS.

Hạn chế : Giải pháp của bạn phải mất trong vài phút hoặc ít hơn để chạy trên đầu vào 6. Điều này không nhằm loại bỏ các thuật toán thời gian theo cấp số nhân, nhưng nó nhằm loại bỏ các thuật toán thời gian theo cấp số nhân, chẳng hạn như vũ phu cưỡng bức trên tất cả các bộ cạnh.

Đầu vào: Bất kỳ số nguyên không âm.

Đầu vào có thể bằng bất kỳ phương tiện tiêu chuẩn nào, bao gồm STDIN, tham số dòng lệnh, đầu vào chức năng, v.v.

Đầu ra: Số lượng cây riêng biệt có nhiều đỉnh như đầu vào.

Đầu ra có thể bằng bất kỳ phương tiện tiêu chuẩn nào, bao gồm STDOUT, trả về hàm, v.v.

Ví dụ: 0, 1, 2, 3, 4, 5, 6, 7 nên trả lại 1, 1, 1, 1, 2, 3, 6, 11.

Ghi điểm: Mã golf, theo byte. Có thể mã ngắn nhất giành chiến thắng!

Sơ hở tiêu chuẩn bị cấm.

Câu trả lời:


3

CJam (69 byte)

]qi:X,{1e|,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/W\+_1,*X=\_W%.*:+-Y/z

Bản demo trực tuyến

Giải trình

01z

.*:+{.*:+}:F~0


Chúng tôi sử dụng chức năng tạo phụ trợ cho A000081 , có thuật ngữ có sự lặp lại

a[0] = 0
a[1] = 1
For n >= 1, a[n+1] = (sum_{k=1}^n a[n-k+1] * sum_{d|k} d * a[d]) / n

dkd×a[d]dk % d == 0 ? d : 0a.*akanN\f{1$%!*}W$.*:+

M

a[n+1]=1nk=1na[nk+1]×M[k]

aM1nn+1a

 qi:X,{   ,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/

Điểm của hàm tạo phụ trợ được cho bởi phần công thức của A000055:

G.f.: A(x) = 1 + T(x) - T^2(x)/2 + T(x^2)/2,
where T(x) = x + x^2 + 2*x^3 + ... is the g.f. for A000081.

a

[x=0]+a[x]+12(a[x/2]i=0na[i]×a[ni])

a[x/2]x1,*X=

0\+a[0]=0X=0W\+2a[x]+i=0na[i]×a[ni]2a[x]

Vì vậy, chúng tôi đã giải thích

 qi:X,{   ,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/W\+_1,*X=\_W%.*:+-Y/

1]N=1

1]qi:X,1>{ ... }/

X=0a[-1 1]0[x=0]X!+1e|

a1N=0

]qi:X,{ ... /+}/

rõ ràng là chia cho số không. Nhưng nếu chúng ta cố gắng

]qi:X,{1e| ... /+}/

sau đó nó hoạt động. Chúng tôi nhận được

             e# Stack: [] 0
1e|          e# Stack: [] 1
,:):N        e# Stack: [] [1]
{            e# We only execute this loop once
  N\f{1$%!*} e#   1 divides 1, so stack: [] [1]
  W$.*       e#   Remember: if the two arrays supplied to the pointwise operation
             e#   are not the same length then the values from the longer one are
             e#   left untouched. Stack: [] [1]
  :+         e#   Fold over a singleton. Stack: [] 1
}%           e# And that was a map, so stack: [] [1]
1$W%.*:+     e# Another [1] [] .*:+, giving the same result: 1
N,/          e# 1 / 1 = 1
+            e# And we append 1 to a giving [1]

mà tạo ra chính xác giá trị chúng tôi yêu cầu.

X=01[-1](112(1×1))=10111z


1

Bình thường, 35 byte

l{m`SmSSMcXdUQk2.pQusm+L,dhHGhHtQ]Y

Trình diễn.

Chương trình này có thể được chia thành hai phần: Đầu tiên, chúng tôi tạo ra tất cả các cây có thể, sau đó chúng tôi loại bỏ các bản sao.

Mã này tạo ra các cây : usm+L,dhHGhHtQ]Y. Cây được biểu diễn dưới dạng một danh sách các cạnh, tương tự như thế này:

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

Mỗi số là viết tắt của một đỉnh và cứ hai số là một cạnh. Nó được xây dựng bằng cách liên tục thêm một cạnh đặt cược cho mỗi đỉnh có thể tồn tại và một đỉnh mới được tạo và thêm nó vào từng cây có thể từ bước trước. Điều này tạo ra tất cả các cây có thể, vì tất cả các cây có thể được tạo bằng cách liên tục thêm một đỉnh và một cạnh từ nó vào cây hiện có. Tuy nhiên, cây đẳng hình sẽ được tạo ra.

Tiếp theo, đối với mỗi cây, chúng tôi thực hiện mọi việc dán nhãn lại. Điều này được thực hiện bằng cách ánh xạ trên tất cả các hoán vị có thể có của các đỉnh ( m ... .pQ), và sau đó chuyển cây từ thứ tự chuẩn sang thứ tự đó, với XdUQk. dlà cây, klà hoán vị.

Sau đó, chúng tôi tách các cạnh thành các danh sách riêng biệt với c ... 2, sắp xếp các đỉnh trong mỗi cạnh với SM, sắp xếp các cạnh trong cây với S, đưa ra một đại diện đại bác cho mỗi cây. Hai bước này là mã mSSMcXdUQk2.pQ.

Bây giờ, chúng tôi có một danh sách các danh sách bao gồm mọi khả năng dán nhãn lại của mỗi cây. Chúng tôi sắp xếp các danh sách này với S. Bất kỳ hai cây đẳng cấu phải có thể được chuyển vào nhóm cây. Sử dụng thực tế này, chúng tôi chuyển đổi từng danh sách thành một chuỗi với `, sau đó tạo thành tập hợp các danh sách đó với {và xuất độ dài của nó với l.

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.