의존성 그래프 시각화


22

이 과제의 목표 는 트리 형태로 종속성 그래프를 시각화하는 프로그램 을 작성하는 것입니다. 이 문맥에서 "종속성 그래프"는 지시 된 그래프에 지나지 않습니다. 여기에 설명 된 시각화 방법은 일부 의존성 관계를 설명하는 그래프에 가장 적합합니다 (운동으로, 과제를 읽은 후 방향 중 하나의 방향을 바꾸어보십시오) 샘플 그래프를보고 결과가 유용한 지 확인하십시오.)

프로그램에 대한 입력 은 하나 이상의 대상 정의 로 구성되며 이는 형식의 행입니다.

Target DirectDependency1 DirectDependency2 ...

, 대상 및 관련 직접 종속성 (있는 경우 ) 정의 대상과 해당 종속성을 통칭하여 객체 라고 합니다 . 개체가 대상이 아닌 종속성으로 만 나타나는 경우 종속성이 없습니다. 입력에 나타나는 모든 객체 세트를 Γ 라고 합니다. 입력 형식에 대한 자세한 내용은 입력 및 출력 섹션을 참조하십시오.

객체 쌍 AB 에 대해 다음 과 같이 말합니다.

  • A는 에 따라 B (등가 적으로, B가 요구하는 ) 경우, A가 직접에 따라 B , 또는 경우 A는 직접에 따라 B ' B' 에 따라 B 일부 객체에 대해, B ' ;
  • A는 적절히에 따라 B (등가 적으로, B는 적절하게 요구하는 경우) A가 에 따라 B B가 에 의존하지 않는.

우리는 Γo 가 아닌 궁극의 객체 ʀooᴛ를 정의하여 어떤 객체도 ʀooᴛ를 직접 요구하지 않으며, 모든 객체 A 에 대해 ʀooᴛ 는 A 가 Γ에 있고 A 가 아닌 경우에만 A에 직접 의존합니다 . 제대로 Γ에서 모든 객체에 의해 요구되는 (즉, ʀooᴛ 직접에 따라 다른 개체에 의존하지 않는 경우 , 또는에 따라 모든 객체 경우 A는 또한 요구하는 .)

출력 트리

우리는 루트 노드가 ʀooᴛ 인 트리를 구성하고 각 노드의 자식이 직접적인 의존성을 갖도록합니다. 예를 들어, 입력이 주어지면

Bread Dough Yeast
Dough Flour Water
Butter Milk

결과 트리는

출력 트리 예

또는 ASCII 형식으로

ʀooᴛ
+-Bread
| +-Dough
| | +-Flour
| | +-Water
| +-Yeast
+-Butter
  +-Milk

. 프로그램의 출력 은 위에 정의 된 트리이며 ʀooᴛ 노드 없이 인쇄 됩니다 . 예를 들어 위의 입력에 해당하는 출력은

Bread
+-Dough
| +-Flour
| +-Water
+-Yeast
Butter
+-Milk

. 출력 트리의 레이아웃에 대한 자세한 설명은 나중에 제공됩니다.

노드 순서

주어진 부모 노드의 자식 노드 P가 ,해야 분류 모든 자식에 대한 노드 같은 것을 와 BP , A는 표시되기 전에 B 경우만

  • 이 자식 노드가 존재 CP가 되도록, A는 정상적으로 요구하는 CC에 선행하거나 같음 B 와 동일한 순서에 따라, 또는 ,
  • A는 알파벳순 선행 B를 (기타 preceisely, 선행 B ASCII 정렬을 사용) 존재하지 어떠한 자 노드 CP 되도록, B는 적절하게 요구하는 C를 , 및 C에 선행하거나 같음 동일한 순서에 따라, .

(수학적 문제를 찾는 사람들은이 관계가 잘 정의되어 있으며 실제로는 총계가 엄격하다는 것을 보여주고 싶을 수도 있습니다. Γ이 유한하다는 것을 잊지 마십시오!)

예를 들어, 입력이 주어지면

X D C B A
B D
C A

출력은

X
+-A
+-D
+-B
| +-D
+-C
  +-A

. A이전에 표시 B하고, B이전에 나타납니다 C그들의 알파벳 순서에; 알파벳순으로 D표시되기 B때문에,에 의해 올바르게 요구되기 A때문에. B그리고 C이전에 표시되지 않는 D노드를,이 존재하기 때문에 그들이 즉, 알파벳을 앞에에도 불구하고 B, 즉 제대로 필요 D하고, 해당 등호 B(즉, 자체), 그리고 진행할 때 C, 같은 규칙에 따라.

반복

예를 들어 둘 이상의 객체에 필요한 경우 동일한 객체 A 가 출력에 두 번 이상 나타날 수 있습니다. 경우 A는 자신의 종속성이없는, 특별한 취급이 경우에는 필요하지 않습니다. 그렇지 않으면 출력의 상세도를 최소화하고 순환 종속성으로 인한 무한 재귀를 피하기 위해 A 의 종속성은 첫 번째 항목 에만 나열되며 다른 조상은 다른 A 노드의 형제가 아닙니다 . 다른 A 발생 에는 자식이 없어야하며 다음과 같이 공백과 줄임표가 있어야합니다 .A...

예를 들어, 입력이 주어지면

IP Ethernet
TCP IP
UDP IP
WebRTC TCP UDP

출력은

WebRTC
+-TCP
| +-IP
|   +-Ethernet
+-UDP
  +-IP ...

. 순환 종속성과 조상 고려 사항을 모두 갖춘 또 다른 예로

Rock Scissors
Paper Rock
Scissors Paper

결과

Paper
+-Rock ...
Rock
+-Scissors ...
Scissors
+-Paper ...

. 예를 들어, 첫 번째 항목은 Rock상위 항목 Paper이 다른 Rock노드 의 형제 이므로 종속성이 나열되지 않습니다 . 두 번째 Rock노드 의 부모 인 ʀooᴛ (출력에 표시되지 않음)에는 Rock형제가 없기 Rock때문에이 노드에 대한 종속성 이 나열됩니다.

출력 트리 레이아웃

나는 나무가 ASCII 아트로 표현되어야하는 방법을 알고 있다고 확신하지만 (만약 있다면이 섹션을 건너 뛰십시오) 완전성을 위해 ...

ʀooᴛ의 자식 노드는 들여 쓰기없이 별도의 줄에 인쇄됩니다. 각 노드 다음에는 동일한 방식으로 동일한 방식으로 인쇄되어 오른쪽에 두 문자가 들여 쓰기 된 하위 노드가 바로 뒤에옵니다. 자식이있는 각 노드에 대해 |(파이프) 문자 로 구성된 세로선 은 마지막 자식 노드를 포함하지 않고 마지막 자식 노드의 행까지 노드의 첫 번째 문자 바로 아래의 문자에서 아래로 확장됩니다. 노드의 들여 쓰기가 0이 아닌 경우, 앞에 +-설명 된 세로선을 겹쳐 쓰고 (부모와 동일한 들여 쓰기 레벨에서 ) 앞에옵니다 .

입력과 출력

STDIN을 통해 또는 동등한 방법을 사용하여 입력을 읽을 수 있습니다 . 빈 줄없다고 가정 하고 마지막 줄은 줄 바꿈 문자로 끝나거나 끝나지 않아야 할 수도 있습니다. 객체 이름은 인쇄 가능한 ASCII 문자 (공백 제외) 로 구성되어 있다고 가정 할 수 있습니다 . 대상 정의의 오브젝트 가 단일 공백 문자 로 구분되고 선행 또는 후행 공백없다고 가정 할 수 있습니다 . 각 대상이 최대 한 번 정의되고 종속성 목록에 반복없다고 가정 할 수 있습니다 .

STDOUT에 출력을 쓰거나 동등한 방법을 사용할 수 있습니다 . 가장 긴 것을 제외한 모든 출력 라인에는 후행 공백이 포함될 수 있습니다. 마지막 출력 행은 개행 문자로 끝나거나 끝나지 않을 수 있습니다.

점수

이것은 code-golf 입니다. 짧은 대답은 , 바이트, 승리.

테스트 사례

프로그램은 다음 각 테스트 사례를 적절한 시간 내에 처리해야합니다.


입력

Depender Dependee
Independent

산출

Depender
+-Dependee
Independent

입력

Earth Turtle
Turtle Turtle

산출

Earth
+-Turtle
  +-Turtle ...

입력

F A C B D I
A B
B A C
D E H
C
G F
J H G C E I
E D
H D
I G

산출

J
+-C
+-E
| +-D
|   +-E ...
|   +-H ...
+-H
| +-D ...
+-G
| +-F
|   +-C
|   +-A
|   | +-B ...
|   +-B
|   | +-C
|   | +-A ...
|   +-D ...
|   +-I ...
+-I
  +-G ...

문명 V 기술 트리

입력

산출


Cygwin syslog-ng 패키지 종속성 그래프

입력

산출


GNU grep regex.c콜 그래프

입력

출력 (후프! SE가 처리하기에는 너무 깁니다.)


5
잘 지정되었습니다!
찰스

노드 순서 섹션의 자체 참조는 머리를 아프게 만듭니다.
재귀

답변:


5

하스켈, 512 바이트

import Data.List
r=reverse
n j|let(w,s)#p|let a?b=or[q!b<GT|(q,r)<-i,a==r,elem q(h p)>elem(a,q)i];a!b|a==b=EQ|a?b||(a<b)>b?a=LT;_!_=GT;l=nub.sortBy(!)$h p;m(v,s)q|h q==[]=(v,[q]:s)|elem q w=(v,[q++" ..."]:s)|(w,x:y)<-(v,[])#q=(w,(q:(u"| "=<<r y)++u"  "x):s)=foldl m(l++w,[])l;c(p,q)=z$p:q:h q;y=z=<<j;i=iterate(nub.sort.(c=<<))y!!length j;h""=[p|p<-id=<<j,and[elem(p,r)i|(r,q)<-i,p==q]];h p=[r|(q,r)<-y,p==q]=unlines=<<r(snd$mempty#"")
u s(x:y)=("+-"++x):map(s++)y
z(x:y)=(,)x<$>y
main=interact$n.map words.lines

Ideone에서 온라인 실행


축하합니다. 아주 좋아요!
Ell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.