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の答えに匹敵するものはありませんが、はるかに効率的です!
これにより、考えられるすべてのソリューションがブルートフォースされますが、失敗はすぐに認識されます。2つのテストケースの場合、ほぼすぐに終了し、より厄介な入力では数秒しかかかりません。また、(あなたは1スペースに名前を付けることはできないものの、受け入れられたノード名に制限がない|
か-
)と(ノード数に制限はありません限り、実用的な制限は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
}
H A
と思いますが、最初の行があり、そのエッジが指定された出力にないため、新しいテストケースが間違っていることに注意してください。編集:問題を特定して修正しました。