Xây dựng đồ thị


15

Trong thử thách này, nhiệm vụ của bạn là xây dựng một biểu đồ vô hướng từ một chuỗi các lệnh. Có một chỉ thị cho mỗi số nguyên không âm và mỗi biến đổi một biểu đồ đã cho thành một biểu đồ mới.

  • Chỉ thị 0: Thêm một nút ngắt kết nối mới.
  • Chỉ thị 1: Thêm một nút mới và kết nối nó với mọi nút hiện có.
  • Chỉ thị m > 1: Loại bỏ tất cả các nút có mức độ (số lượng lân cận) chia hết cho m. Lưu ý rằng 0tất cả đều chia hết m, vì vậy các nút bị ngắt kết nối luôn bị loại bỏ.

Các chỉ thị được áp dụng từng cái một, từ trái sang phải, bắt đầu với biểu đồ trống. Ví dụ, chuỗi [0,1,0,1,0,1,3]được xử lý như sau, được giải thích bằng nghệ thuật ASCII tuyệt vời. Chúng tôi bắt đầu với biểu đồ trống và thêm một đỉnh theo hướng dẫn 0:

a

Sau đó, thêm một đỉnh khác và kết nối nó với đầu tiên, theo chỉ dẫn của 1:

a--b

Chúng tôi thêm một đỉnh bị ngắt kết nối và sau đó một đỉnh được kết nối, theo chỉ dẫn bởi 01:

a--b   c
 \  \ /
  `--d

Chúng tôi lặp lại điều này một lần nữa, theo chỉ dẫn 01:

  ,--f--e
 /  /|\
a--b | c
 \  \|/
  `--d

Cuối cùng, chúng tôi loại bỏ các đỉnh độ 3 ab, theo chỉ dẫn của 3:

f--e
|\
| c
|/
d

Đây là biểu đồ được xác định bởi trình tự [0,1,0,1,0,1,3].

Đầu vào

Một danh sách các số nguyên không âm, đại diện cho một chuỗi các chỉ thị.

Đầu ra

Số lượng các nút trong biểu đồ được xác định bởi trình tự.

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

[] -> 0
[5] -> 0
[0,0,0,11] -> 0
[0,1,0,1,0,1,3] -> 4
[0,0,0,1,1,1] -> 6
[0,0,1,1,0,0,1,1,2,5,7,0,1] -> 6
[0,0,1,1,1,1,5,1,4,3,1,0,0,0,1,2] -> 6
[0,0,1,1,0,0,1,1,5,2,3,0,0,1,1,0,0,1,1,3,4,0,0,1,1,2,1,1] -> 8
[0,0,1,1,0,0,1,1,2,5,7,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,8] -> 14

Quy tắc chi tiết

Bạn có thể viết một chức năng hoặc một chương trình đầy đủ. Số byte ngắn nhất sẽ thắng. Sơ hở tiêu chuẩn là không được phép. Hãy giải thích thuật toán của bạn trong câu trả lời của bạn.


Đã được một tuần, vì vậy tôi đã chấp nhận câu trả lời ngắn nhất. Nếu một cái thậm chí ngắn hơn xuất hiện sau, tôi sẽ cập nhật lựa chọn của mình. Một đề cập đáng trân trọng đến câu trả lời của Peter Taylor , trong đó một số người khác dựa trên, bao gồm cả người chiến thắng.


5
Khi tôi đọc câu hỏi, nghĩ rằng bạn phải thực sự vẽ biểu đồ - Điều này cực kỳ khó khăn , cuộn xuống - oh
Trình tối ưu hóa

@Optimizer Vâng, tôi muốn đặt ra câu hỏi sao cho biểu diễn thực tế của biểu đồ là không quan trọng và khó khăn chính sẽ nằm ở việc thực hiện các chỉ thị. Số lượng các nút chỉ là một cách dễ dàng để kiểm tra tính chính xác.
Zgarb

1
Tôi thực sự thích thử thách này! Nó giống như thiết kế một cấu trúc dữ liệu. Bạn phải tìm ra cách biểu diễn biểu đồ vì các định dạng đầu vào và đầu ra không được gắn với nó.
xnor

Câu trả lời:


4

Bình dương , 37 31

lu?+GH<H2m@Gdf%+*@GTtTs>GTHUGQY

Giải pháp này sử dụng hàm less ( u) để xây dựng danh sách, trong đó mỗi mục tương ứng với một nút còn lại trong danh sách và giá trị của mục tương ứng với việc nút ban đầu được thêm vào theo chỉ thị 0 hoặc 1.

Glà biến tích lũy trong hàm giảm và giữ danh sách đã nói ở trên. Nó được khởi tạo vào danh sách trống , Y.

Hlấy giá trị của từng thành viên Q, đầu vào, từng cái một. Kết quả của biểu thức được gán cho Gmỗi lần và mục tiếp theo của Qđược gán cho Hvà biểu thức được chạy lại.

Để cập nhật Gchính xác, có hai khả năng, một cho chỉ thị 0 hoặc 1 và một cho các chỉ thị khác. Những trường hợp này được phân biệt với chim nhạn? ... <H2 ...

Nếu Hlà 0 hoặc 1, thì tất cả những gì chúng ta cần làm là nối Hvào G. +GHhoàn thành việc này

Mặt khác, điều đầu tiên cần là xác định, đối với mỗi nút trong biểu đồ, nó có bao nhiêu hàng xóm. Điều này được thực hiện trong hai bước:

Đầu tiên, s>GTđếm số lượng nút tại hoặc sau nút đầu vào là 1s. Tất cả đều được kết nối với nút đầu vào, ngoại trừ việc chúng ta sẽ vượt quá 1 nếu nút đầu vào là 1.

Thứ hai, chúng ta cần số lượng nút sớm hơn nút đầu vào được kết nối với nó. Đây là 0 nếu nút đầu vào là 0 và chỉ số của nút đầu vào T, nếu nút đầu vào là 1. Giá trị này sẽ được cung cấp bởi *@GTT. Tuy nhiên, vẫn còn quá nhiều từ phần đầu tiên cần được sửa chữa. Do đó, chúng tôi tính toán *@GTtTthay vào đó, ít hơn 1 nếu nút đầu vào là 1. Các giá trị này được tính tổng, để đưa ra số lượng nút được kết nối với nút đầu vào.

% ... Hsẽ cho 0 là số đó chia hết cho H, và do đó nên loại bỏ và sẽ không cho 0 nếu không.

f ... UGdo đó sẽ đưa ra các chỉ số của đầu vào không nên loại bỏ, vì flà bộ lọc và 0 là sai.

m@Gd chuyển đổi các chỉ số này thành 0 và 1 của các nút tương ứng.

Cuối cùng, một khi danh sách kết quả của các nút có nhãn 0 và 1 được tìm thấy, độ dài của nó được tính ( l) và được in (ẩn).

Ý tưởng rộng rãi nhờ @PeterTaylor.


12

GolfScript (53 byte)

])~{:^1>{.-1:H)-,:T;{..H):H*T@-:T+^%!{;}*}%}{^+}if}/,

Bản demo trực tuyến

Tôi chưa thực sự đánh gôn này, nhưng tôi đã phát hiện ra rằng việc loại bỏ các biến HTbiến không phải là điều tối thiểu.

Đưa đầu vào trên stdin theo định dạng [0 1 2 3]. Lá đầu ra trên thiết bị xuất chuẩn.

Ung dung:

])~{
  :^1>{
    # array of 0s and 1s
    # Each 0 has degree equal to the number of 1s after it
    # Each 1 has degree equal to the number of values before it plus the number of 1s after it
    .-1:H)-,:T;
    {
      # Stack: x
      # T' = T - x is the number of 1s after it
      # H' = H + 1 is the number of values before it
      # Degree is therefore H' * x + T' = H * x + T - x = (H-1)*x + T
      # Keep x unless degree % ^ == 0
      ..H):H*T@-:T+^%!{;}*
    }%
  }{^+}if
}/,

4

CJam, 129 75 73 68 61 46 42 byte

Giải pháp dựa trên thuật toán của Peter:

Lq~{I+I1>{0:U(<:L{LU<,*LU):U>1b+I%},}*}fI,

Mở rộng mã để làm theo.


Giải pháp trước đó (61 byte):

Lq~{:N2<{U):UaN{f+U1$0f=+}*a+}{{:X,(N%_!{X0=L+:L;}*},Lf-}?}/,

Lấy đầu vào từ STDIN như:

[0 0 1 1 0 0 1 1 5 2 3 0 0 1 1 0 0 1 1 3 4 0 0 1 1 2 1 1]

Đầu ra là số trên STDOUT:

8

Thuật toán :

  • Duy trì một biến tăng U lưu trữ id của nút được thêm vào.
  • Duy trì một danh sách danh sách, trong đó, mỗi danh sách là một nút có id duy nhất được tạo bởi phần tử đầu tiên của danh sách và các phần tử còn lại là id của các nút được kết nối.
  • Trong mỗi lần lặp (trong khi đọc các chỉ thị đầu vào),
    • Nếu chỉ thị là 0, thêm [U]vào danh sách danh sách
    • Nếu chỉ thị là 1, thêm Uvào mỗi danh sách trong danh sách danh sách và thêm danh sách khác bao gồm phần tử đầu tiên của mỗi danh sách vàU
    • Để xóa lệnh, tôi lọc ra tất cả các danh sách length - 1chia hết mvà tiếp tục lưu ý phần tử đầu tiên của các danh sách đó. Sau khi lọc, tôi xóa tất cả id đã xóa khỏi danh sách id còn lại.

Mở rộng mã :

Lq~{:N2<{U):UaN{f+U1$0f=+}*a+}{{:X,(N%_!{X0=L+:L;}*},Lf-}?}/,
L                                            "Put an empty array on stack";
 q~                                          "Evaluate the input";
   {                                }/       "For each directive";
    :N                                       "Store the directive in N";
      2<{     ...    }{    ...    }?         "If directive is 0 or 1, run the first";
                                             "block, else second";
{U):UaN{f+U1$0f=+}*a+}
 U):U                                        "Increment and update U (initially 0)";
     a                                       "Wrap it in an array";
      N{         }*                          "Run this block if directive is 1";
        f+                                   "Add U to each list in list of list";
          U1$                                "Put U and list of lists on stack";
             0f=                             "Get first element of each list";
                +                            "Prepend U to the above array";
                   a+                        "Wrap in array and append to list of list";
{{:X,(N%_!{X0=L+:L;}*},Lf-}
 {                   },                      "Filter the list of list on this block";
  :X,(                                       "Get number of connections of this node";
      N%_                                    "mod with directive and copy the result";
         !{        }*                        "If the mod is 0, run this block";
           X0=                               "Get the id of this node";
              L+:L;                          "Add to variable L and update L";
                       Lf-                   "Remove all the filtered out ids from the";
                                             "remaining nodes";
,                                            "After the whole process is completed for"
                                             "all directives, take length of remaining ";
                                             "nodes in the list of list";

Hãy thử nó ở đây


3

Bình thường, 88 80 75 ký tự

JYFHQI!H~Y]]lY)IqH1=Y+m+dlYY]UhlY)VYI&Hq%l@YNH1~J]N))=Ymf!}TJ@YkUlYY;-lYl{J

Tôi đã xong. Có lẽ ai đó có một số mẹo chơi golf.

Ylà danh sách kề của đồ thị. Vì lý do chơi gôn, tôi cũng giữ một nút trong danh sách này, ngay cả sau khi nút bị xóa (Nếu không tôi sẽ phải cập nhật tất cả các chỉ số). Mỗi nút có chính nó là hàng xóm. Danh sách Jtheo dõi các nút bị xóa.

Tôi hiển thị các thay đổi của danh sách kề trong đầu vào ví dụ [0,1,0,1,0,1,3]:

đầu vào 0: Y = [[0]] J = []
đầu vào 1: Y = [[0,1], [0,1]] 0 J = []
đầu vào 0: Y = [[0,1], [0,1], [2]] J = []
đầu vào 1: Y = [[0,1,3], [0,1,3], [2,3], [0,1,2,3]] J = []
đầu vào 0: Y = [[0,1,3], [0,1,3], [2,3], [0,1,2,3], [4]] J = []
đầu vào 1: Y = [[0,1,3,5], [0,1,3,5], [2,3,5], [0,1,2,3,5], [4,5 ], [0,1,2,3,4,5]] J = []
đầu vào 3: Y = [[3,5], [3,5], [2,3,5], [2,3,5], [4,5], [2,3,4,5]] J = [0,1]

Thuật toán sau đó khá đơn giản: Lặp lại tất cả các đầu vào, nếu input == 0: thêm một nút mới với chính nó là hàng xóm, nếu input == 1: thêm một nút mới với tất cả các nút là hàng xóm (cũng là các nút bị xóa) và thêm nút này vào danh sách kề của tất cả các nút, nếu đầu vào> 1: xác định các nút có # xóm-1% đầu vào == 0 và thêm chúng vào J, trong mỗi trường hợp, cập nhật hàng xóm của mỗi nút bằng cách sử dụng J. Cuối cùng, in chiều dài Ytrừ đi chiều dài của (bộ) J.

JYFHQI!H~Y]]lY)IqH1=Y+m+dlYY]UhlY)VYI&Hq%l@YNH1~J]N))=Ymf!}TJ@YkUlYY;-lYl{J
JY                      set J=[]
  FHQ                   for H in: input()
I!H      )                if H==0:
   ~Y]]lY                   Y.append([len(Y)])
IqH1              )       if H==1:
    =Y+                     Y=                 +
       m+dlYY                 old nodes updated
             ]UhlY                              new node with all neighbors
VY                )       for N in range(len(Q)):
  I&Hq%l@YNH1    )          if H>0 and len(Y[N])%H==1:
             ~J]N             J.append(N) //this node gets deleted
=Ym           Y           Y=[           for k in Y]
   f!}TJ@YkUlY               k-filtered  //all items of J are removed
;                       end input for loop
-lYl{J                  print len(Y) - len(set(J))

Sử dụng

Chỉ cần gọi tập lệnh và đưa ra làm đầu vào [0,1,0,1,0,1,3]hoặc một số trường hợp thử nghiệm khác.


3

2

Con trăn 2, 296

s=input();e=[];n=[];c=0
for t in s:
    if t<2:e=e+[[]]if t==0 else [x+[c]for x in e]+[n[:]];n+=[c];c+=1
    else:
        M=zip(*[(i,n[i])for i,x in enumerate(e)if not len(x)%t])
        if M:e=[list(set(z)-set(M[1]))for j,z in enumerate(e)if j not in M[0]];n=list(set(n)-set(M[1]))
print len(n)

Mỗi nút được cung cấp một id duy nhất và id hàng xóm của mỗi nút được ghi lại. Khi lệnh bằng 0, một danh sách lân cận trống được thêm vào nút mới. Khi lệnh là 1, id của tất cả các nút hiện có sẽ trở thành danh sách lân cận cho nút mới và tất cả các danh sách lân cận khác được cập nhật để bao gồm id nút mới. Đối với m> 1, các nút có danh sách lân cận là bội số của m được xóa khỏi danh sách nút và tất cả các danh sách lân cận. Cảm ơn @Optimizer đã bắt lỗi trong phiên bản cũ hơn.


2

NetLogo, 160

to f[t]foreach t[if ? = 0[crt 1]if ? = 1[crt 1[create-links-with other turtles]]if ? > 1[ask turtles with[count my-links mod ? = 0][die]]]show count turtles
end

Việc thực hiện rất đơn giản, đọc từng biểu tượng và thực hiện hành động thích hợp.

to f[t]
  foreach t [
    if ? = 0 [
      crt 1
    ]
    if ? = 1 [
      crt 1 [create-links-with other turtles]
    ]
    if ? > 1 [
      ask turtles with [count my-links mod ? = 0] [die]
    ]
  ]
  show count turtles
end

Bạn có thể chạy từ dòng lệnh như f[0 0 1 1 0 0 1 1 2 5 7 0 1].


2

Ruby 159 157 ( bản demo )

N=Struct.new:l
G=->c{n=[]
c.map{|m|m<1?n<<N.new([]):m<2?(w=N.new([])
n.map{|x|x.l<<w;w.l<<x}
n<<w):(n-=r=n.select{|x|x.l.size%m<1}
n.map{|x|x.l-=r})}
n.size}

Điều này xác định một hàm được gọi là Gsử dụng cú pháp stabby-lambda. Sử dụng G[[0, 1]]để gọi nó với các lệnh 01.

Việc thực hiện khá đơn giản: có một Nodecấu trúc (được gọi Nở trên) chứa các tham chiếu đến tất cả các nút được liên kết thông qua thuộc ltính. Gtạo các nút khi cần thiết và thao tác các liên kết của chúng. Một phiên bản dễ đọc có sẵn ở đây .


1

CJam, 99 97 byte

Lal~{I2<{_0={{If+z}2*));0+a+}{;Iaa}?}{_0=!!{{{_:+I%+}%z}2*));1+a+{{W=},z}2*);z_{);}{a}?}*}?}fI0=,

Vẫn còn rất nhiều để được chơi golf trong này. Thuật toán dựa trên việc theo dõi ma trận kề, nhưng đại diện cho ma trận trống mà không phải xử lý nó đặc biệt là điều khiến tôi đau đầu.

Kiểm tra nó ở đây.

Đầu vào là một mảng kiểu CJam:

[0 0 1 1 0 0 1 1 2 5 7 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 8]

Bạn có thể sử dụng khai thác thử nghiệm này để chạy tất cả các thử nghiệm:

"[]
[5]
[0,0,0,11]
[0,1,0,1,0,1,3]
[0,0,0,1,1,1]
[0,0,1,1,0,0,1,1,2,5,7,0,1]
[0,0,1,1,1,1,5,1,4,3,1,0,0,0,1,2]
[0,0,1,1,0,0,1,1,5,2,3,0,0,1,1,0,0,1,1,3,4,0,0,1,1,2,1,1]
[0,0,1,1,0,0,1,1,2,5,7,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,8]"

","SerN/{
La\~{I2<{_0={{If+z}2*));0+a+}{;Iaa}?}{_0=!!{{{_:+I%+}%z}2*));1+a+{{W=},z}2*);z_{);}{a}?}*}?}fI0=,
N}/

1

Con trăn 2, 174

l=input()
g={}
n=0
for x in l:
 n+=1;g[n]=set()
 if x>1:h={i for i in g if len(g[i])%x};g={i:g[i]&h for i in set(g)&h}
 if x==1:
  for i in g:g[i]^={n};g[n]^={i}
print len(g)

Điều này có lẽ vẫn có thể được chơi golf rất nhiều.

Tôi đã sử dụng một từ điển g để đại diện cho biểu đồ. Các nút được gắn nhãn bằng số và chúng ánh xạ tới tập hợp các nút liền kề. Điều này có nghĩa là mỗi bản cập nhật của một cạnh cần phải được thực hiện tại cả hai điểm cuối của nó.

Chỉ số nút mới được tạo bằng cách đếm lên n. Mỗi lần, tôi tạo một nút trống mới n. Đối với lệnh0 , nó chỉ còn lại. Đối với lệnh 1, nó được kết nối với nhau qua nút g[i]^={n};g[n]^={i}; sử dụng xor làm cho nút của nó không được kết nối với chính nó. Đối với các lệnh> 1, nó sẽ bị xóa ngay lập tức.

Việc lọc các nút có mức độ là bội số được thực hiện bằng cách trước tiên tìm các nút còn lại (h ), sau đó đưa andnó vào danh sách các nút và hàng xóm của mỗi nút.

Cuối cùng, số lượng mục trong từ điển đồ thị là câu trả lời.


0

Toán học, 223 byte

Wow, điều này hóa ra lâu hơn tôi mong đợi.

f=(g={};t=Append;l=Length;m=ListQ;h=Flatten;k=Position;o=If;(d=#;o[d==0,g=g~t~{},o[d==1,g=o[m@#,t[#,l@g+1],#]&/@g;g=t[g,h@k[g,_?m,1]],g=o[l@#~Mod~d==0,0,#]&/@g;p=h@k[g,0];(c=#;g=#~DeleteCases~c&/@g)&/@p]])&/@#;g~Count~_?m)&

Sử dụng:

f@{0, 1, 0, 1, 0, 1, 3}

Dưới đây là kết quả từ các trường hợp thử nghiệm:

f /@ {
  {},
  {5},
  {0, 0, 0, 11},
  {0, 1, 0, 1, 0, 1, 3},
  {0, 0, 0, 1, 1, 1},
  {0, 0, 1, 1, 0, 0, 1, 1, 2, 5, 7, 0, 1},
  {0, 0, 1, 1, 1, 1, 5, 1, 4, 3, 1, 0, 0, 0, 1, 2},
  {0, 0, 1, 1, 0, 0, 1, 1, 5, 2, 3, 0, 0, 1, 1, 0, 0, 1, 1, 3, 4, 0, 0, 1, 1, 2, 1, 1},
  {0, 0, 1, 1, 0, 0, 1, 1, 2, 5, 7, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 8}
}

Out: {0, 0, 0, 4, 6, 6, 6, 8, 14}

Ít chơi gôn hơn:

f = (
   a = #;
   g = {};
   Table[
    If[a[[n]] == 0,
     AppendTo[g, {}],
     If[a[[n]] == 1,
      g = If[ListQ@#, Append[#, Length@g + 1], #] & /@ g; 
      g = Append[g, Flatten@Position[g, _?ListQ, 1]],
      If[a[[n]] > 1,
       g = If[Mod[Length@#, a[[n]]] == 0, 0, #] & /@ g;
       p = Flatten@Position[g, 0];
       (c = #; g = DeleteCases[#, c] & /@ g) & /@ p
       ]
      ]
     ],
    {n, Length@a}];
   Count[g, _?ListQ]
   ) &

Cách thức hoạt động này là bằng cách biểu thị biểu đồ dưới dạng danh sách "danh sách hàng xóm".
Đối với chỉ thị 0 , tôi chỉ cần thêm một danh sách trống.
Đối với chỉ thị 1 , tôi nối thêm danh sách tất cả các nút trước đó và thêm nút mới vào tất cả các nút trước đó.
Đối với một lệnh > 1 , tôi đã loại bỏ các nút được chỉ định và cập nhật phần còn lại.

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.