Xây dựng biểu đồ đường / biểu đồ liên hợp


8

Giới thiệu

Cho một đồ thị vô hướng G, chúng ta có thể xây dựng một đồ thị L (G) (được gọi là đồ thị đường hoặc đồ thị liên hợp) biểu thị các kết nối giữa các cạnh trong G. Điều này được thực hiện bằng cách tạo một đỉnh mới trong L (G) cho mọi cạnh trong G và kết nối các đỉnh này nếu các cạnh mà chúng đại diện có một đỉnh chung.

Dưới đây là một ví dụ từ Wikipedia cho thấy việc xây dựng biểu đồ đường (màu xanh lá cây).

Biểu đồ G Các đỉnh mới đại diện cho mỗi cạnh trong G Các đỉnh được kết nối khi các cạnh của chúng trong G được kết nối Biểu đồ đường L (G)

Một ví dụ khác, lấy biểu đồ G này với các đỉnh A, B, C và D.

    A
    |
    |
B---C---D---E

Chúng ta tạo một đỉnh mới cho mỗi cạnh trong G. Trong trường hợp này, cạnh giữa A và C được biểu thị bằng một đỉnh mới gọi là AC.

   AC

 BC  CD  DE

Và kết nối các đỉnh khi các cạnh mà chúng đại diện có một đỉnh chung. Trong trường hợp này, các cạnh từ A đến C và từ B đến C có đỉnh C chung, do đó các đỉnh AC và BC được kết nối.

   AC
  /  \
 BC--CD--DE

Biểu đồ mới này là biểu đồ đường của G!

Xem Wikipedia để biết thêm thông tin.

Thử thách

Đưa ra danh sách kề cho biểu đồ G, chương trình của bạn sẽ in hoặc trả về danh sách kề cho biểu đồ đường L (G). Đây là môn đánh gôn, vì vậy câu trả lời có ít byte nhất sẽ thắng!

Đầu vào

Danh sách các cặp chuỗi đại diện cho các cạnh của G. Mỗi cặp mô tả các đỉnh được kết nối bởi cạnh đó.

  • Mỗi cặp (X, Y) được đảm bảo là duy nhất, có nghĩa là danh sách sẽ không chứa (Y, X) hoặc một giây (X, Y).

Ví dụ:

[("1","2"),("1","3"),("1","4"),("2","5"),("3","4"),("4","5")]
[("D","E"),("C","D"),("B","C"),("A","C")]

Đầu ra

Một danh sách các cặp chuỗi đại diện cho các cạnh của L (G). Mỗi cặp mô tả các đỉnh được kết nối bởi cạnh đó.

  • Mỗi cặp (X, Y) phải là duy nhất, có nghĩa là danh sách sẽ không chứa (Y, X) hoặc một giây (X, Y).

  • Đối với bất kỳ cạnh (X, Y) nào trong G, đỉnh mà nó tạo trong L (G) phải được đặt tên XY (các tên được nối với nhau theo cùng thứ tự mà chúng được chỉ định trong đầu vào).

Ví dụ:

[("12","13"),("12","14"),("12","25"),("13","14"),("13","34"),("14","34"),("14","45"),("25","45"),("34","45")]
[("DE","CD"),("CD","CB"),("CD","CA"),("BC","AB")]

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

[] -> []

[("0","1")] -> []

[("0","1"),("1","2")] -> [("01","12")]

[("a","b"),("b","c"),("c","a")] -> [("ab","bc"),("bc","ca"),("ca","ab")]

[("1","2"),("1","3"),("1","4"),("2","5"),("3","4"),("4","5")] -> [("12","13"),("12","14"),("12","25"),("13","14"),("13","34"),("14","34"),("14","45"),("25","45"),("34","45")]

4
Tôi không thấy bất cứ điều gì trong câu hỏi loại trừ một đầu vào như [("1","23"),("23","4"),("12","3"),("3","4")], mà đầu ra có lẽ là [("123","234"),("123","34")], không thể được giải thích chính xác. Tôi nghĩ cách duy nhất để khắc phục điều này là chỉnh sửa để đảm bảo rằng đầu vào sẽ không bao giờ chứa những sự mơ hồ như vậy, nhưng nếu câu hỏi này đã được đăng trong hộp cát thì tôi đã đề nghị nên bớt quy định về việc đặt tên các đỉnh trong đầu ra.
Peter Taylor

2
Thêm vào nhận xét của Peter Taylor, chúng ta có thể giả sử rằng các tên đỉnh đều dài 1 ký tự không?
- Phục hồi Monica

Câu trả lời:


2

Ruby, 51 byte

->a{a.combination(2){|x,y|p [x*'',y*'']if(x&y)[0]}}

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

Đối với mỗi kết hợp của hai cạnh, nếu chúng có một đỉnh chung (nghĩa là nếu phần tử đầu tiên của giao điểm của chúng là không nil), hãy in một mảng chứa hai cạnh thành STDOUT.


2

JavaScript (Firefox 30-57), 77 byte

a=>[for(x of a=a.map(x=>x.join``))for(y of a)if(x<y&&x.match(`[${y}]`))[x,y]]

Giả sử tất cả các đầu vào là các chữ cái đơn (tốt, bất kỳ ký tự đơn nào khác ^]).


Điều gì làm cho Firefox 30-57 trở nên đặc biệt cho câu trả lời này?
Đêm2

1
@ Night2 Cú pháp hiểu mảng chỉ được hỗ trợ trong các phiên bản Firefox đó.
Neil

2

Brachylog , 13 byte

{⊇Ċ.c¬≠∧}ᶠcᵐ²

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

Với tất cả các trường hợp thử nghiệm

(-1 byte thay thế l₂bằng Ċ, nhờ @Firthize.)

{⊇Ċ.c¬≠∧}ᶠcᵐ²   Full code
{       }ᶠ      Find all outputs of this predicate:
 ⊇Ċ.             A two-element subset of the input
    c            which when its subarrays are concatenated
     ­          does not have all different elements
                 (i.e. some element is repeated)
       ∧         (no further constraint on output)
          cᵐ²   Join vertex names in each subsubarray in that result

Bạn có thể sử dụng biến bị ràng buộc Ċ(vài) thay vì l₂để lưu một byte.
Gây tử vong vào

2

K (ngn / k) , 45 39 33 29 30 byte

(*>:)#(3=#?,/)#,/{x,/:\:x}@,:'

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

,:' bọc mỗi cạnh trong danh sách 1 yếu tố

{ }@ áp dụng một hàm với đối số ngầm x

x,/:\:xnối từng bên trái xvới mỗi bên phải x, lấy một ma trận kết quả - tất cả các cặp cạnh

,/ làm phẳng ma trận

( )# bộ lọc

(3=#?,/)#chỉ lọc những cặp có phép nối ( ,/) có số đếm ( #) gồm đúng 3 ?phần tử duy nhất ( )

Điều này loại bỏ các cạnh như ("ab";"ab")("ab";"cd")từ danh sách.

(*>)#chỉ lọc những cặp có hoán vị sắp xếp giảm dần ( >) bắt đầu bằng ( *) a 1 (khác 0 là boolean true)

Trong trường hợp của chúng tôi, hoán vị giảm dần có thể là 0 1hoặc 1 0.


1

Làm thế nào fƇđược sử dụng trong Jelly? Nếu tôi đọc nó trong tài liệu, cả hai đều là bộ lọc. flà " Bộ lọc; xóa các phần tử khỏi x không có trong y. " và Ƈlà " Bộ lọc (bí danh cho Ðf). Giữ tất cả các mục thỏa mãn điều kiện. ". Có phải chúng luôn được sử dụng cùng nhau? Được Ƈsử dụng để đóng bộ lọc f? Như trong, f...Ƈtương tự như ʒ...}trong 05AB1E? Hoặc có /(" Giảm hoặc giảm khôn ngoan. ") Có liên quan gì với nó không? Chỉ cần cố gắng để hiểu mã và tôi bị nhầm lẫn bởi hai lệnh lọc khác nhau (và cách cả hai được sử dụng ở đây). :)
Kevin Cruijssen

2
@KevinCruijssen Không, fƇlà hai thứ hoàn toàn riêng biệt. Bạn có thể nghĩ fnhư ngã tư (cho hai danh sách, nó sẽ trả về các yếu tố chung của họ) và Ƈcũng giống như ʒtrong 05AB1E. Tóm Œclại : trả về tất cả các kết hợp có thể có của hai phần tử từ danh sách, sau đó Ƈchỉ giữ những phần tử thỏa mãn liên kết (tức là hàm Jelly) f/, trả về giao điểm của hai mục. Nhưng flà một dyad (hàm hai đối số) và chúng ta cần áp dụng nó vào danh sách hai phần tử, vì vậy chúng ta phải sử dụng /, giảm bớt.
Ông Xcoder

Ah ok, điều đó có ý nghĩa hơn nhiều. Tôi đoán thuật ngữ 'bộ lọc' ftrong các tài liệu, mặc dù đúng, chủ yếu làm tôi bối rối với bộ lọc thực tế Ƈđang được sử dụng. Giải thích của bạn về " đưa ra hai danh sách, trả lại các yếu tố chung của chúng " đã làm cho tất cả rõ ràng. Và tôi thực sự có cảm giác /được sử dụng để chuyển đổi dữ liệu của Jelly bằng cách nào đó. Trên thực tế, bây giờ tôi thấy phần 6.6 Giảm trong Hướng dẫn trên wiki Jelly giải thích cách nó xuất hiện một con đê và đẩy một đơn nguyên giảm (về cơ bản là 2 đối số so với danh sách các cặp làm đối số). Cảm ơn, tất cả rõ ràng bây giờ!
Kevin Cruijssen

1

MATL , 13 byte

2XN!"@Y:X&n?@

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

Không tệ như tôi mong đợi đầu vào mảng di động. Về cơ bản, ý tưởng tương tự như câu trả lời Ruby của @ Doorknob .

2XN   % Get all combinations of 2 elements from the input
!     % Transpose
"     % Iterate over the columns (combinations)
@     % Push the current combination of edges
Y:    % Split it out as two separate vectors
X&n   % Get the number of intersecting elements between them
?@    % If that's non-zero, push the current combination on stack
      % Implicit loop end, valid combinations collect on the stack 
      %  and are implicitly output at the end

0

C (gcc) , 173 byte

Đầu vào ivà đầu ra olà các mảng phẳng, kết thúc null. Tên đầu ra có thể dài tới 998 ký tự trước khi nó bị hỏng.

#define M(x)o[n]=malloc(999),sprintf(o[n++],"%s%s",x[0],x[1])
f(i,o,j,n,m)char**i,**j,**o;{for(n=0;*i;i+=2)for(j=i;*(j+=2);)for(m=4;m--;)strcmp(i[m/2],j[m%2])||(M(i),M(j));}

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


Đề xuất *xthay vì x[0]int**thay vìchar**
trần mèo

0

Toán học 23 byte

EdgeList[LineGraph[#]]&

Thí dụ: g = Graph[{1 <-> 2, 2 <-> 3, 3 <-> 4, 2 <-> 4 }]

nhập mô tả hình ảnh ở đây

EdgeList@LineGraph[g]

(*

{2 <-> 1, 3 <-> 2, 4 <-> 1, 4 <-> 2, 4 <-> 3}

*)


0

Bình thường , 7 byte

@F#.cQ2

Hãy thử nó ở đây!

Nếu tham gia là cần thiết, 10 byte

sMM@F#.cQ2

Hãy thử nó ở đây!


Đầu ra của bạn không có mẫu yêu cầu. Bạn cần xâu chuỗi các nút.
DavidC

@DavidC Tôi không thấy lý do tại sao điều đó lại cần thiết và tôi không thể xác định bất kỳ phần nào trong phạm vi thử thách yêu cầu điều đó, nhưng tôi đã thêm một phiên bản tham gia cùng họ.
Ông Xcoder

Tham gia đã được sử dụng trong tất cả các trường hợp thử nghiệm. Trong trường hợp của tôi, tham gia chi phí 9 byte. Bạn đã có thể làm điều đó chỉ với 3 byte bổ sung. Ấn tượng!
DavidC

0

Ngôn ngữ Wolfram 64 53 byte

""<>#&/@#&/@Select[#~Subsets~{2},IntersectingQ@@#&]&

Tìm tất cả các danh sách đầu vào Subsetcó độ dài 2, Selectcác nút trong đó các nút của một cặp giao nhau với các nút của một cặp khác (chỉ ra rằng các cặp chia sẻ một nút) và StringJoincác nút cho tất cả các cặp được chọn.

Mã này đặc biệt khó đọc vì nó sử dụng 4 hàm thuần túy ( còn gọi là "ẩn danh").

Mã này sử dụng dấu ngoặc nhọn, "{}", làm dấu phân cách danh sách, theo thông lệ trong Ngôn ngữ Wolfram.

Lưu 1 byte nhờ ông Xcoder.


Thí dụ

""<>#&/@#&/@Select[#~Subsets~{2},IntersectingQ@@#&]&[{{"1","2"},{"1","3"},{"1","4"},{"2","5"},{"3","4"},{"4","5"}}]

(*{{"12", "13"}, {"12", "14"}, {"12", "25"}, {"13", "14"}, {"13", "34"}, {"14", "34"}, {"14", "45"}, {"25", "45"}, {"34", "45"}}*)

Hiện tại của bạn thực sự là 65 byte, không phải 64. Tuy nhiên, bạn có thể chơi golf 1 byte với Select[#~Subsets~{2},IntersectingQ@@#&]/.{a_,b_}:>{""<>a,""<>b}& - Hãy thử trực tuyến!
Ông Xcoder

0

Python 2 , 109 byte

lambda a:[(s,t)for Q in[[''.join(p)for p in a if x in p]for x in set(sum(a,()))]for s in Q for t in Q if s<t]

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

Đối với mỗi nút x(được phát hiện bằng cách tạo một tập hợp từ danh sách các cạnh được làm phẳng), hãy tạo một danh sách các cặp pxthành viên; sau đó, đối với mỗi danh sách đó Q, hãy tìm các cặp riêng biệt, riêng biệt bên trong Q(tính duy nhất / sự khác biệt được thi hành thông qua if s<t).


0

C # 233 byte

static void c(List<(string a,string b)>i,List<(string,string)>o){for(int m=0;m<i.Count;m++){for(int n=m+1;n<i.Count;n++){if((i[n].a+i[n].b).Contains(i[m].a)||(i[n].a+i[n].b).Contains(i[m].b)){o.Add((i[m].a+i[m].b,i[n].a+i[n].b));}}}}

Thí dụ

using System;
using System.Collections.Generic;

namespace conjugateGraphGolf
{
    class Program
    {
        static void Main()
        {
            List<(string a, string b)>[] inputs = new List<(string, string)>[]
            {
                new List<(string, string)>(),
                new List<(string, string)>() {("0", "1")},
                new List<(string, string)>() {("0", "1"),("1", "2")},
                new List<(string, string)>() {("a","b"),("b","c"),("c","a")},
                new List<(string, string)>() {("1","2"),("1","3"),("1","4"),("2","5"),("3","4"),("4","5")}
            };

            List<(string, string)> output = new List<(string, string)>();

            for(int i = 0; i < inputs.Length; i++)
            {
                output.Clear();
                c(inputs[i], output);

                WriteList(inputs[i]);
                Console.Write(" -> ");
                WriteList(output);
                Console.Write("\r\n\r\n");
            }

            Console.ReadKey(true);
        }

        static void c(List<(string a,string b)>i,List<(string,string)>o){for(int m=0;m<i.Count;m++){for(int n=m+1;n<i.Count;n++){if((i[n].a+i[n].b).Contains(i[m].a)||(i[n].a+i[n].b).Contains(i[m].b)){o.Add((i[m].a+i[m].b,i[n].a+i[n].b));}}}}

        public static void WriteList(List<(string a, string b)> list)
        {
            Console.Write("[");
            for(int i = 0; i < list.Count; i++)
            {
                Console.Write($"(\"{list[i].a}\",\"{list[i].b}\"){(i == list.Count - 1 ? "" : ",")}");
            }
            Console.Write("]");
        }
    }
}
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.