Perl, 65 59 55 54 byte
Bao gồm +2 cho -ap
Chạy với kích thước cây trên STDIN:
for i in `seq 24`; do echo -n "$i: "; vines.pl <<< $i; echo; done
vines.pl
:
#!/usr/bin/perl -ap
$_=map{${"-@F"%$_}|=$_=$$_|$"x$p++.1;/.\b/g}1-$_..-1
Giải trình
Nếu bạn viết lại cây
3
|
2 4
\ /
1
|
0
đến một nơi mà mỗi nút chứa tập hợp của tất cả tổ tiên và chính nó:
{3}
|
{2,3} {4}
\ /
\ /
{1,2,3,4}
|
{0,1,2,3,4}
Sau đó, chúng ta có thể mô tả ví dụ: tất cả các nút đường dẫn từ 4 đến 3 là:
- Tất cả các nút có chứa 3 nhưng không phải 4 (đi xuống từ 3)
- Tất cả các nút có chứa 4 nhưng không phải 3 (đi xuống từ 4)
- Nút cao nhất chứa cả 3 và 4 (nối)
Số cạnh ít hơn một số nút nên chúng ta có thể sử dụng số đó để bỏ qua điểm nối, vì vậy số cạnh trên đường dẫn từ 4 đến 3 là 3 vì:
- Số lượng nút chứa 3 nhưng không phải nút 4: 2
- Số lượng nút chứa 4 nhưng không phải nút 3: 1
Lưu ý rằng điều này cũng hoạt động đối với một đường dẫn trực tiếp đến mục tiêu của nó, ví dụ: đối với đường dẫn từ 3 đến 2, số cạnh là 1 vì:
- Số lượng nút chứa 2 nhưng không phải nút 3: 0
- Số lượng nút chứa 3 nhưng không phải nút 2: 1
Sau đó chúng ta có thể tổng hợp tất cả các kết hợp này.
Thay vào đó, nếu bạn chỉ nhìn vào một nút, ví dụ nút 2 với tập hợp tổ tiên {2,3}
. Nút này sẽ đóng góp một lần khi xử lý đường dẫn 2 to 1
vì nó chứa 2 nhưng không phải là 1. Nó sẽ không đóng góp gì cho đường dẫn 3 to 2
vì nó có cả 2 và 3, nhưng nó sẽ đóng góp một lần khi xử lý đường dẫn 4 to 3
vì nó có 3 nhưng không 4. Nói chung, một số trong tập hợp tổ tiên của một nút sẽ đóng góp một cho mỗi hàng xóm (một mức thấp hơn cao hơn) không có trong tập hợp. Ngoại trừ yếu tố tối đa (4 trong trường hợp này) chỉ đóng góp cho hàng xóm thấp 3 vì không có đường dẫn5 to 4
. Simular 0 là một mặt, nhưng vì 0 luôn nằm ở gốc cây và chứa tất cả các số (đó là phép nối cuối cùng và chúng ta không đếm số lần tham gia) nên không bao giờ có bất kỳ đóng góp nào từ 0 nên dễ dàng nhất là chỉ để lại nút 0 hoàn toàn
Vì vậy, chúng ta cũng có thể giải quyết vấn đề bằng cách xem tập hợp tổ tiên cho mỗi nút, đếm các đóng góp và tổng trên tất cả các nút.
Để dễ dàng xử lý hàng xóm, tôi sẽ biểu diễn tập hợp tổ tiên dưới dạng một chuỗi khoảng trắng và 1 trong đó mỗi 1 ở vị trí p biểu thị rằng n-1-p là tổ tiên. Vì vậy, ví dụ trong trường hợp n=5
1 của chúng tôi tại vị trí 0 chỉ ra 4 là tổ tiên. Tôi sẽ rời khỏi không gian dấu. Vì vậy, đại diện thực tế của cây tôi sẽ xây dựng là:
" 1"
|
" 11" "1"
\ /
\ /
"1111"
Lưu ý rằng tôi đã bỏ qua nút 0 sẽ được đại diện bởi "11111"
vì tôi sẽ bỏ qua nút 0 (nó không bao giờ đóng góp).
Tổ tiên không có hàng xóm thấp hơn hiện được biểu thị bằng phần cuối của chuỗi 1. Tổ tiên không có hàng xóm cao hơn hiện được biểu thị bằng bắt đầu chuỗi 1, nhưng chúng ta nên bỏ qua bất kỳ bắt đầu nào của chuỗi khi bắt đầu chuỗi vì điều này sẽ đại diện cho đường dẫn 5 to 4
không tồn tại. Sự kết hợp này hoàn toàn phù hợp với regex /.\b/
.
Việc xây dựng chuỗi tổ tiên được thực hiện bằng cách xử lý tất cả các nút theo thứ tự n-1 .. 1
và ở đó đặt 1 ở vị trí cho chính nút đó và thực hiện "hoặc" vào hậu duệ.
Với tất cả những gì chương trình đủ dễ hiểu:
-ap read STDIN into $_ and @F
map{ }1-$_..-1 Process from n-1 to 1,
but use the negative
values so we can use a
perl sequence.
I will keep the current
ancestor for node $i in
global ${-$i} (another
reason to use negative
values since $1, $2 etc.
are read-only
$$_|$"x$p++.1 "Or" the current node
position into its ancestor
accumulator
$_= Assign the ancestor string
to $_. This will overwrite
the current counter value
but that has no influence
on the following counter
values
${"-@F"%$_}|= Merge the current node
ancestor string into the
successor
Notice that because this
is an |= the index
calculation was done
before the assignment
to $_ so $_ is still -i.
-n % -i = - (n % i), so
this is indeed the proper
index
/.\b/g As explained above this
gives the list of missing
higher and lower neighbours
but skips the start
$_= A map in scalar context
counts the number of
elements, so this assigns
the grand total to $_.
The -p implicitly prints
Lưu ý rằng thay thế /.\b/
bằng cách /\b/
giải quyết phiên bản tròn của vấn đề này, nơi tarzan cũng đi theo con đường0 to n-1
Một số ví dụ về cách các chuỗi tổ tiên trông (được đưa ra theo thứ tự n-1 .. 1
):
n=23:
1
1
1
1
1
1
1
1
1
1
1
11
1 1
1 1
1 1
11 11
1 1
11 1 1 11
1 1
1111 11 11 1111
111111111 111111111
1111111111111111111111
edges=68
n=24:
1
1
1
1
1
1
1
1
1
1
1
1
1 1
1 1
1 1
1 1
1 1
1 1 1 1
1 1
11 1 1 11
1 1 1 1
1 1 1 1
1 1
edges=82