ノードのネットワークを描く


24

(名前は26個のノードまでのネットワークがあるAZazあなたの願いどおりに)。ノードのすべてのペアは接続または切断できます。ノードは、最大4つの他のノードに接続できます。あなたの仕事は、ネットワークを2Dダイアグラムに描くことです。このタスクが可能になるように入力が与えられます(出力セクションのその他の制約を参照)。


フォーマット

入力

  • (文字のペアAZaへのzあなたの願いどおり)。それらは任意の順序でソートされません。
  • オプション-ペアの数

出力

  • ノード間の実際のリンクを示すASCII図面。ノードはato zまたはAtoで与えられ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

@ Marco13それは、ほとんどの場合、課題をオフトピックとしてクローズするでしょう。
デニス

@ghosts_in_the_codeモデレーターに質問するためにフラグを使用しないでください。何かに関するフィードバックが必要な場合は、常にThe Nineteenth Byteがあります。
デニス

@Dennis OK、ごめんなさい。私は今までチャットをしたことがないので、どのように機能するのかわかりません。
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コード内の2 文字は、最大のxおよびy座標を指定します。D(= 13)を選んだのは、それがすべての場合に十分であるべきだと思うからです。しかし、プログラムを高速化するためにそれらを他の値に変更することができます。たとえば、3と4を代わりに使用する場合、2番目の例は1〜2分以内に終了します。


私は高速な解決策を要求しませんでしたが、決定論的な解決策を要求すべきでした。しかし、質問があまりにも長く続いているので、私はそれを変更しません。
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の答えに匹敵するものはありませんが、はるかに効率的です!

これにより、考えられるすべてのソリューションがブルートフォースされますが、失敗はすぐに認識されます。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
}

最後に!2か月が経ちました。私は個人的にこのような答えをゴルフに賛成していません。このサイトの人々からのみ要求されました。
ghosts_in_the_code

@ghosts_in_the_codeあなたがコードゴルフを望まないなら、あなたが使うことができる他の多くの客観的な勝利基準があります(明らかに、今ではこのチャレンジは投稿されているので変更できません)。時間ベースの例:特定のハードウェア(特定のEC2インスタンス/ラズベリーパイ/など)で結果を生成するのが最も速い、制限時間内の一連のテストで最もコンパクトな出力、1つのテスト内の一連のテストでサポートされる最大ネットワーク制限時間(1日など、特定のハードウェアに柔軟性を持たせる)。次回サンドボックスを使用してみてください。人々はあなたが目的を選ぶのを助けることができます。
デイブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.