Vẽ một mạng lưới các nút


24

Có một mạng lên tới 26 nút (tên Ađến Zhoặc ađể ztheo mong muốn của bạn). Mỗi cặp nút có thể được kết nối hoặc ngắt kết nối. Một nút có thể được kết nối với tối đa 4 nút khác. Nhiệm vụ của bạn là vẽ mạng theo sơ đồ 2D. Đầu vào sẽ được cung cấp sao cho nhiệm vụ này là có thể (xem thêm các ràng buộc trong phần đầu ra).


định dạng

Đầu vào

  • Cặp chữ cái ( AđểZ hoặc ađể ztheo mong muốn của bạn). Chúng không được sắp xếp theo thứ tự nào.
  • Tùy chọn - số lượng cặp

Đầu ra

  • Một bản vẽ ASCII cho thấy các liên kết thực tế giữa các nút. Nodes được đưa ra bởi ađến zhoặc Ađến Z. Sử dụng -cho các liên kết ngang và |cho các liên kết dọc. Các liên kết có thể có độ dài bất kỳ (khác không) nhưng chúng phải là các đường ngang / dọc thẳng không uốn cong . Không gian có thể được thêm vào miễn là họ không làm biến dạng hình ảnh.

Bạn không được sử dụng các phần dựng sẵn giúp bố trí đồ thị. Các phần dựng sẵn liên quan đến đồ thị khác có thể được cho phép (mặc dù các giải pháp không có phần dựng sẵn sẽ được đánh giá cao hơn). Mã ngắn nhất sẽ thắng.


Dữ liệu mẫu

Đầu vào

A B
B F
B L
F K
L K
K R
K S
R P
S J
S P
J A
T V
V N

Đầu ra

A - B - F   T - V
|   |   |       |
|   L - K - R   N
|       |   |
J ----- S - P

Đầu vào

H C
G H
A B
B F
B C
F G
C D
D A

Đầu ra

A - B ----- F
|   |       |
D - C - H - G

1
Tôi cho rằng các câu hỏi trước đây của tôi đã được trả lời đầy đủ, nhưng lưu ý rằng trường hợp thử nghiệm mới là sai vì dòng đầu tiên là H Avà cạnh đó không nằm trong đầu ra đã cho. Chỉnh sửa: vấn đề được xác định và khắc phục.
Peter Taylor

2
Có thể thay đổi nó thành "Mã đầu tiên (làm việc) chiến thắng"? ;-) Nghiêm túc mà nói, đây là một thử thách riêng, ngay cả khi không chơi gôn ...
Marco13

@ Marco13 Điều đó rất có thể sẽ khiến thách thức đóng lại ngoài chủ đề.
Dennis

@ghosts_in_the_code Vui lòng không sử dụng cờ để đặt câu hỏi cho người kiểm duyệt. Nếu bạn cần phản hồi về điều gì đó, luôn có Byte thứ mười chín .
Dennis

@Dennis ok, xin lỗi. Tôi chưa bao giờ trò chuyện trước đây, vì vậy tôi không biết nó hoạt động như thế nào.
ghosts_in_the_code

Câu trả lời:


3

CJam, 142

Bạn đã không yêu cầu một giải pháp tối ưu, xác định hoặc nhanh chóng, vì vậy bạn hãy vào đây:

qN%Sf%::c_s_&:Aff#:E;{A{;[DmrDmr]2f*}%:C;E{Cf=~.-:*}%0m1{E{Cf=$~1$.-_:g:T\:+,1>\ff*\f.+T0="-|"=f+~}%CA.++:L2f<__&=!}?}gS25*a25*L{~2$4$=\tt}/N*

Dùng thử trực tuyến

Điều này tạo ra tọa độ ngẫu nhiên cho mỗi chữ cái và kiểm tra nếu bố cục có thể chấp nhận được (các chữ cái cạnh xếp hàng và không có giao điểm), cho đến khi nó được. Nó trở nên chậm chạp trong tâm trí khi bạn thêm nhiều cạnh.

Hai Dchữ cái trong mã xác định tọa độ x và y tối đa; Tôi đã chọn D(= 13) vì tôi nghĩ rằng nó là đủ cho tất cả các trường hợp, cứ thoải mái chứng minh tôi sai. Nhưng bạn có thể thay đổi chúng thành các giá trị khác để tăng tốc chương trình, ví dụ ví dụ thứ 2 sẽ kết thúc trong vòng một hoặc hai phút nếu bạn sử dụng 3 và 4 thay thế.


Tôi đã không yêu cầu một giải pháp nhanh chóng, nhưng có lẽ tôi nên yêu cầu một giải pháp xác định. Nhưng bây giờ câu hỏi đã được đưa ra quá lâu, tôi sẽ không thay đổi nó.
ghosts_in_the_code

@ghosts_in_the_code không quá khó để làm cho nó mang tính quyết định - hãy thử tất cả các kết hợp tọa độ. Nhưng nó có lẽ sẽ dài hơn và chậm hơn nhiều, và cũng ăn rất nhiều bộ nhớ.
aditsu

3

C, 813 byte

#include<map>
#include<set>
#include<cstdlib>
typedef int I;typedef char*C;I a,t,s,h;struct p{I x,y;}j,k;std::map<I,std::set<I>>l;std::map<I,p>g;C m,M="  |-";I L(I n,C q,C Q){j=g[n],h=1;for(I o:l[n])if(g.find(o)!=g.end())if(!(a=(k=g[o]).y==j.y)&&k.x^j.x)h=0;else for(I x=j.x,y=j.y,e=k.y*s+k.x,b,d=(k.x<j.x||k.y<j.y)?-1:1;a?x+=d:y+=d,(b=y*s+x)^e;m[b]=q[a])if(m[b]^Q[a]){h=0;break;}}I N(){for(auto i:g)for(I n:l[i.first])if(g.find(n)==g.end())return n;for(auto i:l)if(g.find(a=i.first)==g.end())return a;exit(puts(m));}I f(){for(I n=N(),x,y=0,b;y<s;y+=2)for(x=0;x<s;x+=2)m[b=y*s+x]==*M?g[n]={x,y},m[b]=n,L(n,M+2,M),h&&f(),L(n,M,M+2),m[b]=*M,g.erase(n):0;}I main(I c,C*v){for(;--c;l[a].insert(s),l[s].insert(a))a=v[c][0],s=v[c][1];t=l.size(),s=t|1;memset(m=(C)calloc(s,s),*M,s*s-1);for(a=1;a<s;++a)m[a*s-1]=10;f();}

Lấy đầu vào làm đối số dòng lệnh, ví dụ:

./network AB BF BL FK LK KR KS RP SJ SP JA TV VN

Không nơi nào cạnh tranh với câu trả lời của aditsu theo kích cỡ, nhưng hiệu quả hơn nhiều!

Điều này sẽ vũ phu tất cả các giải pháp có thể, nhưng sẽ nhanh chóng nhận ra thất bại khi nó đi. Đối với hai trường hợp thử nghiệm, nó kết thúc gần như ngay lập tức và dường như chỉ mất vài giây cho các đầu vào khó xử hơn. Nó cũng không giới hạn tên nút được chấp nhận (mặc dù bạn không thể đặt tên cho một khoảng trắng, |hoặc- ) và không có giới hạn về số lượng nút (miễn là tất cả các tên khớp với một byte, vì vậy giới hạn thực tế là 252 nút, và nó sẽ bị chậm lại rất lâu trước khi đạt được điều đó).

Có rất nhiều phạm vi để tăng tốc điều này; rất nhiều lối thoát ngắn mạch đã bị mất khi chơi golf, và có những phần có thể được chuyển ra khỏi các vòng nóng. Ngoài ra một số quan sát đối xứng có thể làm giảm đáng kể vị trí của 2 nút đầu tiên, trong số những thứ khác.


Phá vỡ:

#include<map>
#include<set>
#include<cstdlib>
typedef int I;
typedef char*C;
I a,t,s,h;                // Variables shared between functions
struct p{I x,y;}          // Coord datatype
j,k;                      // Temporary coord references
std::map<I,std::set<I>>l; // Bidirectional multimap of node links
std::map<I,p>g;           // Map of nodes to positions
C m,                      // Rendered grid
M="  |-";                 // Lookup table for output characters

// Line rendering function
// Sets h to 1 if all lines are drawn successfully, or 0 if there is a blocker
I L(I n,C q,C Q){
  j=g[n],h=1;
  for(I o:l[n])                  // For each connection to the current node
    if(g.find(o)!=g.end())       // If the target node has been positioned
      if(!(a=(k=g[o]).y==j.y)&&k.x^j.x)h=0; // Fail if the nodes are not aligned
      else
        for(I x=j.x,y=j.y,             // Loop from node to target
          e=k.y*s+k.x,
          b,d=(k.x<j.x||k.y<j.y)?-1:1;
          a?x+=d:y+=d,(b=y*s+x)^e;
          m[b]=q[a])                   // Render character (| or -)
          if(m[b]^Q[a]){h=0;break;}    // Abort if cell is not blank
}

// Next node selection: finds the next connected node to try,
// or the next unconnected node if the current connected set is complete.
// Displays the result and exits if the entire graph has been rendered.
I N(){
  for(auto i:g)for(I n:l[i.first])  // Search for a connected node...
    if(g.find(n)==g.end())return n; // ...and return the first available
  for(auto i:l)                     // Else search for an unconnected node...
    if(g.find(a=i.first)==g.end())
      return a;                     // ...and return the first available
  exit(puts(m));                    // Else draw the grid to screen and stop
}

// Recursive brute-force implementation
I f(){
  for(I n=N(),x,y=0,b;y<s;y+=2) // Loop through all grid positions
    for(x=0;x<s;x+=2)
      m[b=y*s+x]==*M            // If the current position is available
       ?g[n]={x,y},             // Record the location for this node
        m[b]=n,                 // Render the node
        L(n,M+2,M),             // Render lines to connected nodes
        h&&f(),                 // If line rendering succeeded, recurse
        L(n,M,M+2),             // Un-render lines
        m[b]=*M,g.erase(n)      // Un-render node
       :0;
}

// Input parsing and grid setup
I main(I c,C*v){
  // Parse all inputs into a bidirectional multi-map
  for(;--c;l[a].insert(s),l[s].insert(a))a=v[c][0],s=v[c][1];
  t=l.size(),s=t|1; // Calculate a grid size
  // Allocate memory for the grid and render newlines
  memset(m=(C)calloc(s,s),*M,s*s-1);
  for(a=1;a<s;++a)m[a*s-1]=10;
  f(); // Begin recursive solving
}

Cuối cùng! Đã 2 tháng rồi. Cá nhân tôi không ủng hộ việc chơi golf như vậy, tôi chỉ được yêu cầu bởi những người của trang web này.
ghosts_in_the_code

@ghosts_in_the_code nếu bạn không muốn chơi gôn, có rất nhiều tiêu chí chiến thắng khách quan khác mà bạn có thể sử dụng (mặc dù rõ ràng, bạn không thể thay đổi thử thách này ngay bây giờ khi nó được đăng). Các ví dụ dựa trên thời gian sẽ là: nhanh nhất để tạo kết quả trên phần cứng cụ thể (ví dụ: cụ thể EC2 / raspberry pi / v.v.), đầu ra nhỏ gọn nhất cho pin thử nghiệm trong một giới hạn thời gian, mạng lớn nhất được hỗ trợ từ pin thử nghiệm trong một giới hạn thời gian (ví dụ một ngày, cho phép linh hoạt trên phần cứng cụ thể). Hãy thử sử dụng hộp cát lần sau; mọi người có thể giúp bạn chọn một mục tiêu.
Dave
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.