วาดเครือข่ายของโหนด


24

มีเครือข่ายถึง 26 โหนดคือ (ชื่อAไปZหรือaเพื่อzให้เป็นไปตามความปรารถนาของคุณ) โหนดทุกคู่อาจเชื่อมต่อหรือตัดการเชื่อมต่อ โหนดอาจเชื่อมต่อกับมากที่สุด 4 โหนดอื่น ๆ งานของคุณคือการวาดเครือข่ายในแผนภาพ 2D จะได้รับการป้อนข้อมูลเพื่อให้งานนี้เป็นไปได้ (ดูข้อ จำกัด เพิ่มเติมในส่วนเอาต์พุต)


รูป

อินพุต

  • คู่ของตัวอักษร ( AไปยังZหรือaเพื่อzตามความต้องการของคุณ) พวกเขาจะไม่เรียงลำดับใด ๆ
  • ไม่บังคับ - จำนวนคู่

เอาท์พุต

  • ASCII drawing ที่แสดงลิงก์จริงระหว่างโหนด โหนดจะได้รับจากaการzหรือเพื่อA Zใช้-สำหรับลิงค์แนวนอนและ|สำหรับลิงค์แนวตั้ง ลิงค์ที่อาจจะมีความยาวใด ๆ (ไม่ใช่ศูนย์) แต่พวกเขาควรจะเป็นแนวนอนตรง / เส้นแนวตั้งที่ทำไม่ได้โค้งงอ สามารถเพิ่มช่องว่างได้หากไม่ทำให้รูปภาพเสียโฉม

คุณไม่สามารถใช้บิวด์อินที่ช่วยในการจัดวางของกราฟ บิวด์อินที่เกี่ยวข้องกับกราฟอื่น ๆ อาจได้รับอนุญาต (แม้ว่าโซลูชันที่ไม่มีบิวด์อินจะนิยมมากกว่า) รหัสที่สั้นที่สุดชนะ


ตัวอย่างข้อมูล

อินพุต

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

เอาท์พุต

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

อินพุต

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

เอาท์พุต

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

1
ฉันคิดว่าคำถามก่อนหน้าของฉันมีคำตอบเพียงพอ แต่โปรดทราบว่ากรณีทดสอบใหม่ไม่ถูกต้องเพราะบรรทัดแรกคือH Aและขอบนั้นไม่อยู่ในผลลัพธ์ที่กำหนด แก้ไข: ระบุปัญหาและแก้ไขแล้ว
Peter Taylor

2
อาจเปลี่ยนเป็น "รหัสแรก (ใช้งานได้) ชนะ" หรือไม่ ;-) อย่างจริงจังนี้เป็นสิ่งที่ท้าทายในตัวเองได้โดยไม่ต้องเล่นกอล์ฟ ...
Marco13

@ Marco13 นั่นน่าจะเป็นการปิดความท้าทายเป็นหัวข้อปิด
Dennis

@ghosts_in_the_code โปรดอย่าใช้ธงเพื่อถามคำถามผู้ดูแล หากคุณต้องการคำติชมเกี่ยวกับบางสิ่งมีByte ที่สิบเก้าเสมอ
Dennis

@ เดนนิสโอเคขอโทษ ฉันไม่เคยแชทมาก่อนเลยไม่รู้เลยว่ามันทำงานยังไง
ghosts_in_the_code

คำตอบ:


3

CJam, 142

คุณไม่ได้ขอวิธีแก้ไขปัญหาที่ดีที่สุดกำหนดขึ้นหรือรวดเร็วดังนั้นคุณจะไปที่นี่:

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ตัวอักษรสองตัวในรหัสระบุพิกัด x และ y สูงสุด ฉันเลือกD(= 13) เพราะฉันคิดว่ามันควรจะเพียงพอสำหรับทุกกรณีอย่าลังเลที่จะพิสูจน์ฉัน แต่คุณสามารถเปลี่ยนเป็นค่าอื่น ๆ เพื่อเร่งความเร็วโปรแกรมเช่นตัวอย่างที่ 2 ควรเสร็จภายในหนึ่งหรือสองนาทีหากคุณใช้ 3 และ 4 แทน


ฉันไม่ได้ขอวิธีแก้ปัญหาที่รวดเร็ว แต่บางทีฉันควรจะขอคำสั่งกำหนด แต่ตอนนี้คำถามได้ถูกตั้งคำถามมานานแล้วฉันจะไม่เปลี่ยนแปลง
ghosts_in_the_code

@ghosts_in_the_code ไม่ควรยากเกินกว่าที่จะกำหนดได้ - ลองชุดพิกัดทั้งหมด แต่มันอาจจะนานกว่าและช้ากว่ามากและกินความทรงจำมากมายเช่นกัน
aditsu

3

C, 813 ไบต์

#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();}

รับอินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่งเช่น:

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

ไม่มีคู่แข่งใกล้เคียงกับคำตอบของ aditsu ตามขนาด แต่มีประสิทธิภาพมากกว่า!

นี่จะเป็นการแก้ปัญหาที่เป็นไปได้ทั้งหมด แต่จะรับรู้ถึงความล้มเหลวได้อย่างรวดเร็ว สำหรับกรณีทดสอบทั้งสองกรณีจะเสร็จสิ้นเกือบจะในทันทีและดูเหมือนว่าจะใช้เวลาเพียงไม่กี่วินาทีในการป้อนข้อมูลที่น่าอึดอัดใจมากขึ้น นอกจากนี้ยังไม่มีข้อ จำกัด สำหรับชื่อโหนดที่ยอมรับ (แม้ว่าคุณจะไม่สามารถตั้งชื่อหนึ่งช่องว่าง|หรือ-) และไม่มีข้อ จำกัด เกี่ยวกับจำนวนโหนด (ตราบใดที่ชื่อทั้งหมดมีขนาดพอดีกับไบต์ดังนั้นข้อ จำกัด ในทางปฏิบัติคือ 252 โหนด และมันจะช้าลงก่อนที่จะถึงคนจำนวนมาก)

มีขอบเขตมากมายสำหรับการเร่งความเร็ว การลัดวงจรจำนวนมากออกจากสนามไปและมีบางส่วนที่สามารถเคลื่อนออกจากลูปร้อนได้ นอกจากนี้การสังเกตความสมมาตรบางอย่างสามารถลดการจัดตำแหน่งของ 2 โหนดแรกอย่างเหนือสิ่งอื่นใด


ทำให้พังถล่ม:

#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
}

ที่สุด! 2 เดือนแล้ว โดยส่วนตัวแล้วฉันไม่ชอบการเล่นกอล์ฟคำตอบฉันต้องการเพียงแค่คนในไซต์นี้เท่านั้น
ghosts_in_the_code

@ghosts_in_the_code หากคุณไม่ต้องการโค้ดกอล์ฟมีเกณฑ์การชนะอื่น ๆ อีกมากมายที่คุณสามารถใช้ได้ (แม้ว่าจะเห็นได้ชัดว่าคุณไม่สามารถเปลี่ยนแปลงความท้าทายนี้ได้ในตอนนี้) ตัวอย่างตามเวลา: เร็วที่สุดในการสร้างผลลัพธ์บนฮาร์ดแวร์เฉพาะ (เช่น EC2 อินสแตนซ์เฉพาะ / raspberry pi / ฯลฯ ), เอาต์พุตขนาดเล็กที่สุดสำหรับแบตเตอรี่ของการทดสอบภายในเวลา จำกัด , เครือข่ายที่ใหญ่ที่สุดที่รองรับจากแบตเตอรี่ของการทดสอบภายใน จำกัด เวลา (เช่นหนึ่งวันทำให้มีความยืดหยุ่นในฮาร์ดแวร์เฉพาะ) ลองใช้กล่องทดลองครั้งต่อไป ผู้คนสามารถช่วยคุณเลือกเป้าหมาย
เดฟ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.