Đếm các chu kỳ đầu cuối của đồ thị có hướng


8

Bài tập

Bạn phải viết một chương trình hoặc hàm bằng ngôn ngữ bạn chọn để đếm chính xác số chu kỳ đầu cuối của đồ thị có hướng đơn giản.

Loại đồ thị có hướng cụ thể này được biểu diễn dưới dạng một mảng gồm n số nguyên, mỗi số có giá trị ngẫu nhiên được chọn độc lập trong khoảng từ 1 đến n (hoặc 0 và n-1, nếu ngôn ngữ của bạn đếm từ 0). Biểu đồ có thể được coi là mũi tên chỉ từ một chỉ mục (nút) đến một chỉ mục khớp với giá trị được tìm thấy tại chỉ mục bắt đầu.

Hàm của bạn phải có khả năng chấp nhận các biểu đồ lớn, tối đa n = 1024 hoặc bất kỳ kích thước số nguyên nhỏ hơn.

Thí dụ

Hãy xem xét biểu đồ này cho n = 10:

[9, 7, 8, 10, 2, 6, 3, 10, 6, 8]

Chỉ số 1 chứa số 9, do đó, có một mũi tên từ chỉ số 1 đến chỉ số 9. Chỉ số 9 chứa số 6, do đó, có một mũi tên 9 -> 6. Chỉ số 6 chứa 6, là một chu kỳ cuối, tự quay về chính nó.

Chỉ số 2 chứa 7. Chỉ số 7 chứa 3. Chỉ số 3 chứa 8. Chỉ số 8 chứa 10. Chỉ số 10 chứa 8, do đó, đó là chu kỳ đầu cuối thứ hai (8 -> 10 -> 8 -> 10, v.v. ).

Chỉ số 4 -> 10, bước vào chu kỳ đầu cuối thứ hai. Tương tự, chỉ số 5 -> 2 -> 7 -> 3 -> 8, cũng là một phần của chu kỳ đầu cuối thứ hai.

Tại thời điểm này, tất cả các chỉ số (nút) đã được kiểm tra, tất cả các đường dẫn đã được theo dõi và hai chu kỳ đầu cuối duy nhất được xác định. Do đó, hàm sẽ trả về 2 , vì đó là số chu kỳ đầu cuối trong biểu đồ có hướng này.

Chấm điểm

Nhằm mục đích cho mã nhỏ nhất, nhưng đảm bảo rằng nó đếm chính xác các chu kỳ đầu cuối. Mã ngắn nhất sau 1 tuần chiến thắng.

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

Dưới đây là một số trường hợp thử nghiệm để kiểm tra tính chính xác của mã của bạn. Nếu ngôn ngữ của bạn đếm các chỉ số mảng bắt đầu từ 0, tất nhiên bạn phải trừ 1 khỏi giá trị của từng thành phần mảng, để ngăn chặn chỉ mục ngoài giới hạn.

n = 32, 5 chu kỳ:

[8, 28, 14, 8, 2, 1, 13, 15, 30, 17, 9, 8, 18, 19, 30, 3, 8, 25, 23, 12, 6, 7, 19, 24, 17, 7, 21, 20, 29, 15, 32, 32]

n = 32, 4 chu kỳ:

[20, 31, 3, 18, 18, 18, 8, 12, 25, 10, 10, 19, 3, 9, 18, 1, 13, 5, 18, 23, 20, 26, 16, 22, 4, 16, 19, 31, 21, 32, 15, 22]

n = 32, 3 chu kỳ:

[28, 13, 17, 14, 4, 31, 11, 4, 22, 6, 32, 1, 13, 15, 7, 19, 10, 28, 9, 22, 5, 26, 17, 8, 6, 13, 7, 10, 9, 30, 23, 25]

n = 32, 2 chu kỳ:

[25, 23, 22, 6, 24, 3, 1, 21, 6, 18, 20, 4, 8, 5, 16, 10, 15, 32, 26, 25, 27, 14, 13, 12, 9, 9, 29, 8, 13, 31, 32, 1]

n = 32, 1 chu kỳ:

[6, 21, 15, 14, 22, 12, 5, 32, 29, 3, 22, 23, 6, 16, 20, 2, 16, 25, 9, 22, 13, 2, 19, 20, 26, 19, 32, 3, 32, 19, 28, 16]

n = 32, 1 chu kỳ:

[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, 2, 3, 4, 5, 6, 7]

n = 1024, 6 chu kỳ:

[239, 631, 200, 595, 178, 428, 582, 191, 230, 551, 223, 61, 564, 463, 568, 527, 143, 403, 154, 236, 928, 650, 14, 931, 236, 170, 910, 782, 861, 464, 378, 748, 468, 779, 440, 396, 467, 630, 451, 130, 694, 167, 594, 115, 671, 853, 612, 238, 464, 771, 825, 471, 167, 653, 561, 337, 585, 986, 79, 506, 192, 873, 184, 617, 4, 259, 4, 662, 623, 694, 859, 6, 346, 431, 181, 703, 823, 140, 635, 90, 559, 689, 118, 117, 130, 248, 931, 767, 840, 158, 696, 275, 610, 217, 989, 640, 363, 91, 129, 399, 105, 770, 870, 800, 429, 473, 119, 908, 481, 337, 504, 45, 1011, 684, 306, 126, 215, 729, 771, 5, 302, 992, 380, 824, 868, 205, 807, 917, 407, 759, 181, 640, 685, 795, 258, 180, 900, 20, 773, 546, 866, 564, 761, 632, 895, 968, 980, 651, 225, 676, 18, 685, 784, 208, 227, 3, 267, 852, 57, 487, 566, 633, 849, 309, 543, 145, 575, 811, 621, 560, 492, 24, 665, 66, 851, 168, 262, 259, 754, 481, 565, 768, 172, 1012, 241, 3, 370, 985, 389, 82, 779, 744, 829, 836, 249, 975, 909, 840, 226, 867, 499, 192, 909, 972, 735, 252, 785, 545, 486, 186, 1011, 89, 939, 649, 110, 119, 185, 836, 717, 545, 938, 621, 946, 94, 363, 721, 177, 747, 59, 819, 146, 283, 821, 547, 654, 941, 755, 18, 449, 367, 499, 944, 62, 553, 435, 344, 900, 25, 251, 920, 902, 99, 326, 98, 495, 385, 929, 865, 327, 725, 674, 33, 173, 429, 873, 558, 90, 460, 366, 543, 583, 954, 792, 213, 536, 670, 49, 738, 802, 1015, 23, 915, 119, 263, 307, 601, 474, 971, 826, 613, 446, 37, 145, 894, 901, 307, 906, 886, 990, 89, 798, 384, 487, 822, 354, 768, 902, 163, 179, 134, 920, 439, 619, 215, 94, 709, 744, 366, 543, 349, 347, 2, 438, 141, 486, 19, 998, 500, 857, 955, 932, 1, 587, 195, 646, 550, 887, 626, 400, 348, 154, 808, 678, 873, 186, 282, 168, 993, 722, 56, 345, 5, 226, 328, 22, 894, 658, 264, 13, 803, 791, 359, 217, 997, 168, 578, 952, 734, 964, 898, 659, 628, 980, 15, 31, 439, 13, 875, 687, 1004, 1023, 165, 642, 561, 897, 711, 124, 404, 346, 723, 774, 352, 784, 276, 395, 14, 443, 343, 153, 510, 590, 172, 215, 130, 106, 295, 906, 133, 758, 483, 898, 391, 760, 702, 972, 721, 611, 592, 1001, 724, 934, 59, 831, 171, 253, 869, 431, 538, 20, 648, 76, 351, 103, 33, 385, 852, 437, 470, 95, 434, 408, 430, 994, 366, 706, 809, 532, 161, 388, 668, 245, 965, 365, 913, 471, 927, 245, 256, 805, 540, 380, 995, 446, 657, 545, 573, 955, 499, 322, 949, 635, 401, 185, 421, 626, 534, 429, 930, 633, 563, 348, 626, 518, 682, 233, 775, 444, 42, 199, 57, 271, 683, 397, 883, 620, 768, 8, 331, 497, 19, 340, 900, 919, 497, 276, 78, 252, 164, 764, 927, 242, 270, 759, 824, 945, 886, 262, 59, 439, 217, 720, 519, 862, 626, 326, 339, 589, 16, 565, 947, 604, 144, 87, 520, 256, 240, 336, 685, 361, 998, 805, 678, 24, 980, 203, 818, 855, 85, 276, 822, 183, 266, 347, 8, 663, 620, 147, 189, 497, 128, 357, 855, 507, 275, 420, 755, 131, 469, 672, 926, 859, 156, 127, 986, 489, 803, 433, 622, 951, 83, 862, 108, 192, 167, 862, 242, 519, 574, 358, 549, 119, 630, 60, 925, 414, 479, 330, 927, 94, 767, 562, 919, 1011, 999, 908, 113, 932, 632, 403, 309, 838, 341, 179, 708, 847, 472, 907, 537, 516, 992, 944, 615, 778, 801, 413, 653, 690, 393, 452, 394, 596, 545, 591, 136, 109, 942, 546, 57, 626, 61, 587, 862, 829, 988, 965, 781, 849, 843, 815, 60, 928, 784, 388, 341, 491, 565, 83, 110, 164, 38, 1024, 859, 297, 520, 327, 733, 699, 631, 78, 178, 671, 895, 818, 637, 99, 425, 933, 248, 299, 333, 144, 323, 105, 849, 942, 767, 265, 72, 204, 547, 934, 916, 304, 919, 273, 396, 665, 452, 423, 471, 641, 675, 60, 388, 97, 963, 902, 321, 826, 476, 782, 723, 99, 735, 893, 565, 175, 141, 70, 918, 659, 935, 492, 751, 261, 362, 849, 593, 924, 590, 982, 876, 73, 993, 767, 441, 70, 875, 640, 567, 920, 321, 46, 938, 377, 905, 303, 736, 182, 626, 899, 512, 894, 744, 254, 984, 325, 694, 6, 367, 532, 432, 133, 938, 74, 967, 725, 87, 502, 946, 708, 122, 887, 256, 595, 169, 101, 828, 696, 897, 961, 376, 910, 82, 144, 967, 885, 89, 114, 215, 187, 38, 873, 125, 522, 884, 947, 962, 45, 585, 644, 476, 710, 839, 486, 634, 431, 475, 979, 877, 18, 226, 656, 573, 3, 29, 743, 508, 544, 252, 254, 388, 873, 70, 640, 918, 93, 508, 853, 609, 333, 378, 172, 875, 617, 167, 771, 375, 503, 221, 624, 67, 655, 465, 272, 278, 161, 840, 52, 1016, 909, 567, 544, 234, 339, 463, 621, 951, 962, 1019, 383, 523, 279, 780, 838, 984, 999, 29, 897, 564, 762, 753, 393, 205, 31, 150, 490, 156, 796, 586, 676, 773, 465, 489, 1024, 433, 214, 701, 480, 604, 280, 241, 563, 943, 911, 12, 400, 261, 883, 999, 207, 618, 141, 959, 767, 978, 461, 992, 982, 272, 143, 404, 645, 331, 348, 783, 698, 827, 82, 145, 536, 449, 852, 750, 789, 413, 913, 420, 14, 499, 285, 533, 223, 75, 591, 994, 884, 237, 63, 411, 563, 611, 801, 173, 759, 278, 318, 772, 1018, 48, 440, 333, 611, 834, 423, 583, 22, 716, 393, 794, 83, 83, 864, 859, 600, 525, 808, 569, 95, 952, 852, 567, 651, 2, 984, 906, 992, 747, 602, 143, 547, 1008, 940, 245, 633, 378, 193, 771, 965, 648, 437, 873, 591, 664, 271, 777, 274, 742, 68, 429, 825, 144, 55, 272, 279, 6, 400, 485, 66, 311, 663, 441, 23, 988, 726, 48, 624, 302, 617, 120, 653, 810, 641, 142]

Chắc chắn, đây là một trường hợp thử nghiệm chất béo lớn n = 1024. Hy vọng rằng tôi đã không bán nó trong khi đóng gói nó cho Stack Exchange.
phosgene

Làm rõ: Nếu ngôn ngữ sử dụng mảng dựa trên zero, thì tất cả các số trong mảng sẽ dựa trên zero, hay không?
Ypnypn

Vâng đúng rồi. Các số trong mảng sẽ luôn trỏ đến một chỉ mục mảng hợp lệ. Tôi đã sử dụng phương pháp đếm 'kiểu người' bắt đầu từ 1 vì đó là những gì ngôn ngữ của tôi sử dụng và tôi không muốn làm hỏng các ví dụ của mình.
phosgene

Câu trả lời:


2

GolfScript, 25 ký tự

:I{{I=.}I.+,*]I,>$0=}%.&,

Cách tiếp cận tương tự như giải pháp của Keith Randall nhưng trong GolfScript. Lưu ý rằng GolfScript có mảng không có chỉ mục. Kiểm tra trực tuyến .

:I        # Assign input to variable I
{         # Foreach item in I
  {I=.}   # Code block: take the n-th list item
  I.+,*   # Iterate the code block 2*len(I) times
  ]       # and gather result in an array
  I,>     # Take last len(I) items
  $0=     # Get minimum
}%
.&        # Take unique items
,         # Count

Khó tin quá nhiều được thực hiện với rất ít mã.
DavidC

Đó là ngắn ấn tượng.
phosgene

5

Toán học 69

Điều này tìm thấy số lượng các thành phần đồ thị.

f@l_ := Length@WeaklyConnectedComponents@Graph@Thread[Range@Length@l -> l]

Trường hợp thử nghiệm đầu tiên:

v = {8, 28, 14, 8, 2, 1, 13, 15, 30, 17, 9, 8, 18, 19, 30, 3, 8, 25, 23, 12, 6, 7, 19, 24, 17, 7, 21, 20, 29, 15, 32, 32}
f[v]

5


Phân tích

Tạo một danh sách các cạnh được định hướng giữa các chỉ số, (sử dụng ví dụ 1).

Thread[Range@Length@v -> v

{1 -> 8, 2 -> 28, 3 -> 14, 4 -> 8, 5 -> 2, 6 -> 1, 7 -> 13, 8 -> 15, 9 -> 30, 10 -> 17 , 11 -> 9, 12 -> 8, 13 -> 18, 14 -> 19, 15 -> 30, 16 -> 3, 17 -> 8, 18 -> 25, 19 -> 23, 20 -> 12 , 21 -> 6, 22 -> 7, 23 -> 19, 24 -> 24, 25 -> 17, 26 -> 7, 27 -> 21, 28 -> 20, 29 -> 29, 30 -> 15 , 31 -> 32, 32 -> 32}


Graph vẽ biểu đồ hiển thị các thành phần biểu đồ.

ImagePaddingVertexLabels được sử dụng ở đây để hiển thị các chỉ số.

Graph[Thread[Range[Length@v] -> v], ImagePadding -> 30, VertexLabels -> "Name"]

các thành phần

WeaklyConnectedComponents trả về danh sách các đỉnh cho mỗi thành phần.

Length trả về số lượng thành phần.

c = WeaklyConnectedComponents[g]
Length[c]

{{17, 10, 25, 8, 18, 1, 4, 12, 15, 13, 6, 20, 30, 7, 21, 28, 9, 22, 26, 27, 2, 11, 5}, { 14, 3, 19, 16, 23}, {32, 31}, {24}, {29}}

5


Thời gian của danh sách mẫu với 1024 phần tử:

Thời gian: 0,002015 giây

f[z] // AbsoluteTiming

{0,002015, 6}


Để cho vui, đây là hình ảnh của trường hợp thử nghiệm cuối cùng, được vẽ biểu đồ. Tôi đã bỏ qua các nhãn đỉnh; Có quá nhiều.

Graph[Thread[Range[Length@z] -> z], GraphLayout -> "RadialEmbedding"]

đồ thị z


1
Rất súc tích, mặc dù tên hàm 25 ký tự. Điều này có thể chứng minh khó đánh bại. Ngoài ra, nó trông giống như một câu chuyện Chọn cuộc phiêu lưu của riêng bạn.
phosgene

WeaklyConnectedComponentsrất dài dòng. Nhưng nó làm rất nhiều việc. (Người ta không bao giờ nên đánh giá thấp J và các ngôn ngữ tương tự về sự đồng nhất.)
DavidC

Tại một số điểm, tôi nghi ngờ Wolfram sẽ hết ý tưởng và chỉ bắt đầu biến câu trả lời của Stack Exchange thành các chức năng của thư viện, là để biện minh cho các bản phát hành mới.
phosgene

Vâng, tôi hiểu ý của bạn. Hiện tại có hàng ngàn hàm được xây dựng thành Mathicala. Điều kỳ lạ là họ làm việc với nhau rất tốt.
DavidC

Đó là khuôn khổ ban đầu của việc viết lại biểu thức là một ý tưởng tốt chết tiệt. Bây giờ nếu chỉ họ sẽ thực hiện nhiều cấp độ hoàn tác ...
phosgene

2

Python, 132 116 ký tự

def T(V):
 n=len(V);r=range(n);s={}
 for i in r:
    p=[i]
    for k in r+r:p+=[V[p[-1]]]
    s[min(p[n:])]=1
 return len(s)

Đối với mỗi chỉ mục, chúng tôi theo các cạnh cho n bước nhảy, điều này đảm bảo chúng tôi đang ở trong một chu kỳ cuối. Sau đó chúng tôi theo n bước nhảy khác và tìm chỉ số tối thiểu trong chu kỳ đó. Tổng số chu kỳ đầu cuối sau đó chỉ là số lượng cực tiểu khác nhau mà chúng ta tìm thấy.


Tôi thích phương pháp này. Có lẽ có một cách để kết hợp các vòng lặp 'i in r'?
phosgene

Thật buồn khi bạn không thể #define F for i in rtheo phong cách Python, C (++) ... :)
tomsmeding

1

Trong Python:

def c(l):
    if(l==[]):
        return 0
    elif (l[-1]==len(l)):
        return c(l[:-1])+1
    else:
        return c([[x,l[-1]][x==len(l)] for x in l[:-1]])

1
Đây là môn đánh gôn. Vui lòng thêm số byte trong trình của bạn. Bạn có thể muốn xóa khoảng trắng không cần thiết.
Martin Ender

1
Cũng như dấu ngoặc đơn không cần thiết. Họ không cần thiết trong các ifđiều kiện.
dùng12205

c=lambda l:0 if l==[] else c(l[:-1])+1 if l[-1]==len(l) else c([[x,l[-1]][x==len(l)] for x in l[:-1]])là tốt hơn: 102 byte.
ɐɔıʇǝɥʇuʎs

1

J - 61 53 char

Đây là một doozy.

#@([:#/.~[:+./ .*"1/~@e.<~.@(],;@:{~)^:_&.>])@:(<@<:)

Biến <@<:danh sách thành biểu đồ J, trông giống như một danh sách các hộp và hộp tại chỉ mục ichứa tất cả các nút mà nút ikết nối với. Chỉ số J từ 0, vì vậy chúng tôi sử dụng <:để giảm mọi thứ trước khi đấm bốc <.

   (<@<:) 9 7 8 10 2 6 3 10 6 8
+-+-+-+-+-+-+-+-+-+-+
|8|6|7|9|1|5|2|9|5|7|
+-+-+-+-+-+-+-+-+-+-+

Việc <~.@(],;@:{~)^:_&.>]biến mỗi nút thành một danh sách tất cả các nút có thể đạt được từ nó. Người <...&.>]chịu trách nhiệm thực hiện điều này xảy ra với từng nút và ~.@(],;@:{~)^:_thực tế xuất phát từ một gôn J của nhiệm vụ 'nút có thể tiếp cận' này tôi đã thực hiện vài tuần trước.

   (<~.@(],;@:{~)^:_&.>])@:(<@<:) 9 7 8 10 2 6 3 10 6 8
+---+-------+---+---+---------+-+-----+---+-+---+
|8 5|6 2 7 9|7 9|9 7|1 6 2 7 9|5|2 7 9|9 7|5|7 9|
+---+-------+---+---+---------+-+-----+---+-+---+

e.thực hiện một nhiệm vụ thú vị. Nếu đóng "khả năng tiếp cận" của biểu đồ (phiên bản của biểu đồ sao cho nếu có các cạnh có hướng X → Y và Y → Z, chúng ta thêm cạnh X → Z.) Có N nút và cạnh E, thì e.trên biểu đồ này tạo ra một ma trận boolean gồm N hàng và cột E, với True nếu nút tương ứng chia sẻ một nút có thể tiếp cận với cạnh này. Bối rối, nhưng chịu đựng tôi.

   ([:e.<~.@(],;@:{~)^:_&.>])@:(<@<:) 9 7 8 10 2 6 3 10 6 8
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1
0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 1 1 1 1 0 1 1
0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 1 1 1 1 0 1 1
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1
0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 1 1 1 1 0 1 1
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 1 1 1 1 0 1 1

Tiếp theo, chúng ta phải tìm số chu kỳ đầu cuối, tức là số nhóm chia sẻ Trues giữa các cột của chúng. Chúng tôi muốn tạo một bảng nhân của các hàng ( "1/~) và chúng tôi sử dụng một loại sản phẩm bên trong làm phép nhân, một bảng ANDs ghép đôi và sau đó OR tất cả các kết quả với nhau ( +./ .*). Ma trận kết quả là một bảng vuông có True ở mỗi vị trí có hai hàng chia sẻ ít nhất một cột giữa chúng.

   ([:+./ .*"1/~@e.<~.@(],;@:{~)^:_&.>])@:(<@<:) 9 7 8 10 2 6 3 10 6 8
1 0 0 0 0 1 0 0 1 0
0 1 1 1 1 0 1 1 0 1
0 1 1 1 1 0 1 1 0 1
0 1 1 1 1 0 1 1 0 1
0 1 1 1 1 0 1 1 0 1
1 0 0 0 0 1 0 0 1 0
0 1 1 1 1 0 1 1 0 1
0 1 1 1 1 0 1 1 0 1
1 0 0 0 0 1 0 0 1 0
0 1 1 1 1 0 1 1 0 1

Bây giờ tất cả những gì còn lại phải làm là kiểm tra xem có bao nhiêu loại mẫu hàng khác nhau. Vì vậy, chúng tôi thực hiện chính xác điều đó: nhóm các hàng cùng loại ( /.~), báo cáo số lượng trong mỗi nhóm ( #), sau đó lấy số lượng nhóm ( #@).

   #@([:#/.~[:+./ .*"1/~@e.<~.@(],;@:{~)^:_&.>])@:(<@<:) 9 7 8 10 2 6 3 10 6 8
2

Sử dụng trên các ví dụ khác:

   tcc =: #@([:#/.~[:+./ .*"1/~@e.<~.@(],;@:{~)^:_&.>])@:(<@<:)  NB. name
   tcc 8 28 14 8 2 1 13 15 30 17 9 8 18 19 30 3 8 25 23 12 6 7 19 24 17 7 21 20 29 15 32 32
5
   tcc 20 31 3 18 18 18 8 12 25 10 10 19 3 9 18 1 13 5 18 23 20 26 16 22 4 16 19 31 21 32 15 22
4
   tcc 6 21 15 14 22 12 5 32 29 3 22 23 6 16 20 2 16 25 9 22 13 2 19 20 26 19 32 3 32 19 28 16
1
   tcc tentwentyfour  NB. the 1024-node example
6

Thật không may, trường hợp phần tử 1024 bây giờ mất một thời gian rất dài để chấm dứt. Phiên bản trước <:@#@((#~0={.+/@:*"1])^:a:)@e.@(~.@(],;@:{~)^:_&.>~<)@:(<@<:)(61 char) mất hơn một giây để làm điều này.


À đúng rồi, e già tốt. Chức năng, tôi nên đã biết. o_O Tôi đang cảm thấy nhẹ nhàng khi nhìn vào mã của bạn. Làm tốt.
phosgene

0

Con trăn (96)

Rất, rất, rất, rất dựa trên câu trả lời của người dùng 2228078, vì nó hoạt động giống hệt nhau, nhưng được đánh gôn nhiều hơn:

c=lambda l:(1+c(l[:-1])if l[-1]==len(l)else c([[x,l[-1]][x==len(l)]for x in l[:-1]]))if l else 0

(Câu hỏi kỹ thuật: câu trả lời của một người nào đó phải là wiki cộng đồng?)


Bạn có phước lành của tôi để đạo văn. Hãy để nó là một nỗ lực cộng đồng.
phosgene

@ user2790167 Chắc chắn, có ya đi;)
ɐɔı'uʎs

0

Con trăn (89) (87)

def c(G):
 u=i=0
 for _ in G:
  j=i;i+=1
  while j>=0:G[j],j=~i,G[j]
  u+=j==~i
 return u

Ý tưởng chính là bắt đầu tại mỗi nút lần lượt và đi dọc theo đường dẫn từ nó, đánh dấu mỗi nút chúng ta truy cập bằng một nhãn duy nhất cho nút mà chúng ta bắt đầu. Nếu chúng ta từng nhấn một nút được đánh dấu, chúng ta dừng bước và kiểm tra xem điểm đánh dấu có phải là nút tương ứng với nút bắt đầu của chúng ta không. Nếu đó là chúng ta phải đi một vòng, vì vậy chúng ta tăng số chu kỳ lên một.

Trong mã, ulà bộ đếm chu kỳ, ilà nút bắt đầu, jlà nút hiện tại chúng ta đang đi. Nhãn tương ứng với nút bắt đầu ilà phần bổ sung bit của nó ~iluôn âm. Chúng tôi đánh dấu một nút bằng cách trỏ nó vào giá trị đó, ghi đè lên bất kỳ nút nào mà nó thực sự chỉ đến (cẩn thận đi đến nút đó trước khi nó bị quên).

Chúng tôi biết rằng chúng tôi đã nhấn một nút được đánh dấu khi chúng tôi đi đến một "nút" giá trị âm ngay sau đó. Chúng tôi kiểm tra xem giá trị âm đó có phải là nhãn hiện tại để xem liệu chúng tôi đã đi một chu kỳ hay chưa. Vì mỗi nút chúng ta đi được xóa một cách hiệu quả, mỗi chu kỳ sẽ chỉ được đi một lần.

Nó lưu các ký tự để đếm ithủ công với một biến vòng lặp giả _sau đó là for i in range(len(G)). Danh sách Python được lập chỉ mục 0. Nếu họ thay vì 1-lập chỉ mục, chúng ta có thể tiết kiệm được hai nhân vật bằng cách viết j=i=i+1ijlà 1 cho vòng lặp đầu tiên, và ghi j>0ở vị trí của j>=0.

Biên tập:

Chúng ta có thể lưu hai ký tự bằng cách lặp iqua các thành phần của danh sách thay vì các chỉ mục, vì nút không được chỉ ra bởi bất kỳ cạnh nào không quan trọng. Chúng ta phải lặp đi lặp lại set(G)mặc dù để tránh lặp lại một nút bắt đầu mà nó chỉ ra bởi nhiều nút khác.

def c(G):
 u=0
 for i in set(G):
  j=i
  while j>=0:G[j],j=~i,G[j]
  u+=j==~i
 return u

Mã Python ngắn nhất chưa được đăng và phương pháp 'đánh dấu phấn' thú vị. Tôi thích nó.
phosgene
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.