绘制节点网络


24

最多有26个节点的网络(根据您的意愿命名AZa以命名z)。每对节点都可以连接或断开。一个节点最多可以连接四个其他节点。您的任务是在2D图中绘制网络。将给出输入以使此任务成为可能(请参见输出部分中的更多约束)。


格式

输入项

  • 成对的字母(按您的意愿A发送Za发送给z您)。它们没有以任何顺序排序。
  • 可选-对数

输出量

  • ASCII图,显示节点之间的实际链接。节点由ato zAto 给定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并且给定的输出中没有该边缘。编辑:发现并解决问题。
彼得·泰勒

2
也许将其更改为“第一个(工作)代码成功”?;-)严重的是,即使没有打高尔夫球,这本身也是一个挑战...
Marco13 '16

@ Marco13这很有可能使挑战成为题外话。
丹尼斯

@ghosts_in_the_code请不要使用标志来问主持人问题。如果您需要某些事情的反馈,总是有The Nineteenth Byte
丹尼斯

@丹尼斯,对不起。我以前从未聊天过,所以我不知道它是如何工作的。
ghosts_in_the_code

Answers:


3

果酱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)是因为我认为这对所有情况都足够了,请随时证明我做错了。但是您可以将它们更改为其他值以加快程序的运行速度,例如,如果您使用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
}

最后!已经两个月了 我个人不赞成打高尔夫球,但是这个站点的人们只要求我这样做。
ghosts_in_the_code

@ghosts_in_the_code,如果您不希望打高尔夫球,可以使用其他许多客观的获胜标准(尽管显然,现在已经发布,您无法更改此挑战)。基于时间的示例将是:在特定硬件(例如特定的EC2实例/树莓派等)上最快生成结果的结果,在一定时限内最紧凑的输出以用于一连串的测试,最大的网络来自一个测试内的一连串的测试。时间限制(例如一天,允许特定硬件具有灵活性)。下次尝试使用沙盒;人们可以帮助您选择目标。
戴夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.