การแสดงกราฟการพึ่งพา


22

เป้าหมายของความท้าทายนี้คือการเขียนโปรแกรมที่แสดงกราฟการพึ่งพาในรูปแบบของต้นไม้ ในขณะที่ "กราฟการพึ่งพา" ในบริบทนี้ไม่มีอะไรมากไปกว่ากราฟกำกับ แต่วิธีการสร้างภาพที่อธิบายไว้ที่นี่ทำงานได้ดีที่สุดสำหรับกราฟที่อธิบายถึงความสัมพันธ์เชิงพึ่งพาบางประการ (เช่นแบบฝึกหัดหลังจากที่คุณอ่านความท้าทายแล้ว กราฟตัวอย่างและดูว่าผลลัพธ์มีประโยชน์หรือไม่)

การป้อนข้อมูลไปยังโปรแกรมประกอบด้วยหนึ่งหรือมากกว่าเป้าหมายนิยามซึ่งเป็นเส้นของรูปแบบ

Target DirectDependency1 DirectDependency2 ...

กำหนดเป้าหมายและการพึ่งพาโดยตรงที่เกี่ยวข้องหากมี เป้าหมายและการอ้างอิงของพวกเขาจะเรียกว่าวัตถุ ถ้าวัตถุปรากฏขึ้นเป็นการอ้างอิงเท่านั้นและไม่เป็นเป้าหมายวัตถุนั้นจะไม่มีการอ้างอิง ชุดของวัตถุทั้งหมดที่ปรากฏในการป้อนข้อมูลที่เรียกว่าΓ (ดูส่วนอินพุตและเอาต์พุตสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับรูปแบบอินพุต)

สำหรับวัตถุAและBใด ๆเราพูดว่า:

  • Aขึ้นอยู่กับB (เทียบเท่า Aต้องการBโดยA ) ถ้า Aขึ้นอยู่กับ Bโดยตรงหรือถ้า Aขึ้นอยู่กับ B 'โดยตรงและ B'ขึ้นอยู่กับ Bสำหรับวัตถุ Bบางส่วน ;
  • Aขึ้นอยู่กับBอย่างถูกต้อง (เทียบเท่า Aเป็นสิ่งจำเป็นโดยA ) ถ้า Aขึ้นอยู่กับ Bและ Bไม่ได้ขึ้นกับ A

เรากำหนดวัตถุที่ถูกประดิษฐ์ʀooᴛไม่ได้อยู่ในʀเช่นนั้น notoo not ไม่ได้ต้องการโดยตรงจากวัตถุใด ๆ และเช่นนั้นสำหรับวัตถุทั้งหมด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ควรเรียงลำดับเช่นนั้นสำหรับโหนดลูกทั้งหมดAและBของP , Aจะปรากฏขึ้นก่อนBถ้าหาก

  • มีอยู่เด็กโหนดCของPเช่นว่าจะต้องถูกต้องโดยCและCนำหน้าหรือเท่ากับ, Bตามคำสั่งเดียวกัน; หรือ ,
  • ตามลำดับตัวอักษรนำหน้าB (เพิ่มเติม preceisely, แจ๋วBโดยใช้การเปรียบเทียบ ASCII) และมีอยู่ไม่มีเด็กโหนดCของPเช่นว่าBเป็นสิ่งจำเป็นอย่างถูกต้องโดยCและCนำหน้าหรือเท่ากับ,ตามคำสั่งเดียวกัน .

(ผู้ที่กำลังมองหาความท้าทายทางคณิตศาสตร์อาจต้องการแสดงให้เห็นว่าความสัมพันธ์นี้ได้รับการกำหนดไว้อย่างดีและในความเป็นจริงนั้นเป็นคำสั่งที่เข้มงวดโดยสมบูรณ์อย่าลืมว่า fin นั้นมี จำกัด !)

ตัวอย่างเช่นกำหนดอินพุต

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(เช่นตัวเอง) และ preceeds Cตามกฎเดียวกัน

ซ้ำ

วัตถุเดียวกัน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ᴛถูกพิมพ์บนบรรทัดที่แยกกันโดยไม่มีการย่อหน้าใด ๆ ตามลำดับ แต่ละโหนดจะตามด้วยลูกของมันทันทีหากมีพิมพ์ในรูปแบบเดียวกันซ้ำ ๆ โดยเยื้องไปทางขวาสองอักขระ สำหรับแต่ละโหนดที่มีชายด์บรรทัดแนวตั้งประกอบด้วย|อักขระ (ไพพ์) ขยายออกจากอักขระโดยตรงใต้อักขระตัวแรกของโหนดจนกระทั่งแถวของโหนดชายน์สุดท้ายไม่รวมชายด์ของโหนดชายด์สุดท้าย หากการเยื้องของโหนดไม่ใช่ศูนย์มันจะถูกนำหน้าด้วย+-(ในระดับการเยื้องเดียวกับพาเรนต์) เขียนทับเส้นแนวตั้งที่อธิบายไว้ข้างต้น

อินพุตและเอาต์พุต

คุณสามารถอ่านการป้อนข้อมูลผ่าน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

อินพุต

เอาท์พุต


GNU grep regex.cกราฟการโทร

อินพุต

เอาท์พุท (อ้าว! ยาวเกินกว่าที่ SE จะจัดการได้)


5
ดีที่ระบุ!
ไม่ใช่ว่า Charles

การอ้างอิงตนเองในส่วนของ Node ทำให้ฉันปวดหัว
เรียกซ้ำ

คำตอบ:


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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.