Візуалізація графіка залежності


22

Мета цього завдання - написати програму, яка візуалізує графік залежності у вигляді дерева. Хоча "графік залежності" в цьому контексті означає не що інше, як спрямований графік, описаний тут метод візуалізації найкраще працює для графіків, що описують деяке відношення залежності (як вправу, після того, як ви прочитали виклик, спробуйте змінити напрямок одного з зразкові графіки і побачити, чи результат такий же корисний.)

Вхід в програму складається з одного або більше цільових визначень , які такі рядки

Target DirectDependency1 DirectDependency2 ...

, визначення мети та пов'язаних з нею прямих залежностей , якщо такі є. Цілі та їх залежності називаються спільно об'єктами . Якщо об’єкт постає лише як залежність, а не як ціль, він не має залежностей. Сукупність усіх об'єктів, що з’являються на вході, називається Γ . (Див. Розділ «Введення та вихід» для отримання більш детальної інформації про формат введення.)

Для будь-якої пари об'єктів, A і B , ми говоримо, що:

  • A залежить від B (рівнозначно, B вимагається A ), якщо A безпосередньо залежить від B , або якщо A безпосередньо залежить від B ' , а B' залежить від B , для якогось об'єкта B ' ;
  • Чином залежить від B (еквівалентно, В правильно необхідної А ), якщозалежить від B , а B не залежить від А .

Ми визначаємо надуманий об'єкт ʀooᴛ , а не в Γ, таким чином, що ʀooᴛ не вимагається безпосередньо жодним об'єктом, і такий, що для всіх об'єктів A ᴛooᴛ безпосередньо залежить від A, якщо і тільки якщо A знаходиться в Γ, а A не є належним чином вимагається будь-яким об'єктом у Γ (іншими словами, ʀooᴛ безпосередньо залежить від A, якщо жоден інший об'єкт не залежить від A , або якщо всі об'єкти, які залежать від A , також вимагаються від 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 , повинні бути відсортовані , таким чином , що для всіх дочірніх вузлів і Б з Р , з'являється перед B , якщо і тільки якщо

  • існує дочірній вузол З з Р , таким чином, що правильно вимагають C , і C передує або дорівнює, B , в відповідно до того ж порядком; або ,
  • За алфавітом передує B (більш preceisely, A передує B з використанням ASCII сортування,) , і не існує ні дочірнього вузла З з Р , такі , що В належним чином , необхідному 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...

Наприклад, з урахуванням введення

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ᴛ друкуються окремими рядками, без жодних відступів, в порядку. Кожен вузол одразу супроводжується його дітьми, якщо такі є, надруковані однаково, рекурсивно, з відступом двома символами праворуч. Для кожного вузла, у якого є діти, вертикальна лінія, що складається з |(труби) символів, простягається вниз від символу безпосередньо під першим символом вузла, аж до рядка його останнього дочірнього вузла, не враховуючи дітей останнього дочірнього вузла. Якщо відступ вузла не є нульовим, йому передує +-(на тому ж рівні відступу, що і його батьківський), перезаписуючи вертикальну лінію, описану вище.

Вхід і вихід

Ви можете читати дані через STDIN або використовуючи аналогічний метод . Ви можете припустити, що порожніх рядків немає , і вам може знадобитися, щоб останній рядок закінчувався або не закінчувався символом нового рядка. Ви можете припустити, що назви об'єктів складаються з символів для друку ASCII (не включаючи пробіл). Можна припустити, що об'єкти в цільовому визначенні розділені одним символом пробілу , а також немає провідних чи кінцевих пробілів . Ви можете припустити, що кожна ціль визначена щонайбільше одразу і що у її списку залежностей немає повторів .

Ви можете записати висновок в STDOUT або використовувати еквівалентний метод . Усі вихідні лінії, крім найдовшої, можуть містити проміжки. Останній вихідний рядок може або не може закінчуватися символом нового рядка.

Оцінка

Це код-гольф . Найкоротший відповідь , в байтах, виграє.

Випробування

Ваша програма повинна обробити кожен із наведених нижче тестових випадків за розумну кількість часу.


Вхідні дані

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

Вхідні дані

Вихідні дані


regex.cГрафік виклику GNU grep

Вхідні дані

Вихід (Whoops! Занадто довго, щоб SE впорався.)


5
Добре вказано!
Не те, що Чарльз

Самопосилання в розділі Порядок Вузолів болить голова.
рекурсивна

Відповіді:


5

Haskell, 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.