C, 813 bytes
#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();}
Takes input as commandline arguments, e.g.:
./network AB BF BL FK LK KR KS RP SJ SP JA TV VN
Nowhere near competitive with aditsu's answer by size, but much more efficient!
This will brute-force all possible solutions, but will quickly recognise failure as it goes. For the two test cases, it finishes almost immediately, and it seems to only take a few seconds on more awkward inputs. It also has no limitation to the accepted node names (though you can't name one space, | or -) and has no limit on the number of nodes (as long as all names fit in a byte, so the practical limit is 252 nodes, and it will get slow long before reaching that many).
There's plenty of scope for speeding this up; a lot of short-circuit exiting was lost to the golfing, and there's parts which could be moved out of hot-loops. Also some observations of symmetry can dramatically reduce the positioning of the first 2 nodes, among other things.
Breakdown:
#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
}
1I consider that my previous questions have been sufficiently answered, but note that the new test case is wrong because the first line is
H Aand that edge isn't in the given output. Edit: problem identified and fixed. – Peter Taylor – 2016-01-27T14:32:12.8332Maybe change it to "First (working) code wins"? ;-) Seriously, this is challenging on its own, even without golfing... – Marco13 – 2016-01-28T13:59:26.467
@Marco13 That would most likely get the challenge closed as off topic. – Dennis – 2016-01-28T14:49:21.507
@ghosts_in_the_code Please don't use flags to ask moderators questions. If you need feedback on something, there's always The Nineteenth Byte.
– Dennis – 2016-01-28T14:51:19.103@Dennis ok, sorry. I've never been on chat before, so I don't know how it works. – ghosts_in_the_code – 2016-01-28T14:53:49.447
Just click the link, click logged in at the bottom of the page, log in as you usual do, and go back to the chat page. – Dennis – 2016-01-28T15:04:48.213
Will there always be at least one edge? Can there be isolated vertices? Can a node be connected to itself with an edge? – mbomb007 – 2017-02-16T22:39:33.443
@mbomb007 Isolated vertices don't have to be outputted (like in the examples). A node cannot be connected to itself. Your code doesn't need to work for empty input. – ghosts_in_the_code – 2017-02-17T10:42:49.393
"Never mind the golfing requirement for now." Regardless of the difficulty of the answer, answers still need to follow the rules, part of which are that all answers need to make at least an attempt at golfing the code. Please don't encourage people to do otherwise. – Martin Ender – 2017-02-17T11:41:47.857
@MartinEnder Ok then, if you say so. Btw why are non-golfing coding questions not allowed on this site? And which site would they be better to put on? – ghosts_in_the_code – 2017-02-17T12:00:30.197
They just have a different tag. Like [code-challenge], [king-of-the-hill], [code-bowling], etc – mbomb007 – 2017-02-17T14:28:52.873
@mbomb007 Ik. But still it isn't as well accepted if I submit it as code-challenge – ghosts_in_the_code – 2017-02-17T14:43:56.523
It depends how you submit it. But for the most part that's because it needs an objective winning criterion, and the easiest one is byte-count. Any other criterion is likely to be seen as inferior. – mbomb007 – 2017-02-17T15:05:13.120
@mbomb007 Why isn't 'first working solution' an objective criterion? – ghosts_in_the_code – 2017-02-18T06:42:15.083
It is, but only one submission gets to compete. So if you're not first, what's the point in trying? – mbomb007 – 2017-02-19T01:23:47.463
@ghosts_in_the_code what about crossings/overlaps, e.g.
ad,bd,cd,ae,be,ce,af,bf,cf– Rod – 2017-02-20T13:21:26.557@Rod Input will be given such that there's always atleast one way to draw it. – ghosts_in_the_code – 2017-02-20T14:02:36.040