ค้นหาเส้นผ่านศูนย์กลางของกราฟคำ


13

บทนำ

ปริศนาคำศัพท์ยอดนิยมคือการแปลงหนึ่งคำเป็นอีกคำหนึ่งผ่านชุดของขั้นตอนที่แทนที่ตัวอักษรเพียงตัวเดียวและส่งผลให้เกิดคำที่ถูกต้องเสมอ ตัวอย่างเช่น BAG สามารถแปลงเป็น DOG ผ่านเส้นทางห้าขั้นตอน:

BAG -> BAT -> CAT -> COT -> COG -> DOG

เส้นทางที่สั้นกว่านั้นมีอยู่ในกรณีนี้เช่นกัน ตัวอย่างเช่น:

BAG -> BOG -> DOG

หากมีใครวาดกราฟซึ่งจุดยอดถูกติดป้ายกำกับด้วยคำโดยมีขอบระหว่างคำคู่ใด ๆ ที่แตกต่างกันด้วยตัวอักษรหนึ่งตัวเส้นทางที่สั้นที่สุดจาก "BAG" ถึง "DOG" จะประกอบด้วยสองขอบ

ท้าทาย

คุณจะต้องเขียนโปรแกรมที่รับเป็น "พจนานุกรม" ของคำที่ทุกคนมีความยาวเท่ากันแสดงถึงคำที่อนุญาตทั้งหมดที่สามารถปรากฏเป็นขั้นตอนตามเส้นทาง มันควรจะส่งออกอย่างน้อยหนึ่ง "เส้นทางที่สั้นที่สุดที่ยาวที่สุด" นั่นคือเส้นทางระหว่างคำสองคำคือ:

  • ไม่เกินเส้นทางอื่นระหว่างคำทั้งสองนี้

  • อย่างน้อยตราบใดที่เส้นทางที่สั้นที่สุดที่เป็นไปได้ระหว่างคำอื่น ๆ ในรายการ

ในบริบทของกราฟที่อธิบายข้างต้นความยาวของเส้นทางดังกล่าวคือเส้นผ่านศูนย์กลางของกราฟ

ในกรณีที่เสื่อมโทรมซึ่งไม่มีคำใดที่ป้อนเข้าสามารถแปลงเป็นคำอื่น ๆ ได้ให้ส่งออกอย่างน้อยหนึ่งเส้นทางที่มีความยาวศูนย์นั่นคือคำเดียว

ตัวอย่าง

  • อินพุต ["bag", "bat", "cat", "cot", "dot", "dog"] ควรให้เส้นทางผ่านทั้งหกคำในลำดับนั้น (หรือเรียงกลับกัน) เนื่องจากเส้นทางที่สั้นที่สุดจาก " กระเป๋า "เป็น" สุนัข "ในพจนานุกรมนี้เป็นไปได้ยาวที่สุดห้าขั้นตอน

  • อินพุต ["bag", "bat", "bot", "cat", "cot", "dot", "dog"] ควรให้เส้นทาง "bag, bat, bot, dot, dog" และ / หรือ ความผกผัน

  • อินพุต ["code", "golf", "male", "buzz", "mole", "role", "mold", "cold", "gold", "mode"] ควรให้เส้นทางระหว่าง "code" และ "กอล์ฟ"

  • อินพุต ["หนึ่ง", "สอง", "หก", "สิบ"] สอดคล้องกับกราฟที่ไม่มีขอบดังนั้นเอาท์พุทเส้นทางเดียวคำ (ศูนย์ยาว) หนึ่งหรือมากกว่า

  • หากอินพุตมีความยาวไม่เท่ากันสองคำเอาต์พุตจะไม่ถูกกำหนด

กฎระเบียบ

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

3
หากใจเพิ่มอีกสองสามกรณีทดสอบ?
Jonah

เสร็จสิ้น เพิ่มการอภิปรายของกรณีที่กราฟไม่มีขอบ
jnfnt


เราควรยอมรับอินพุตว่าง (คำตอบจะเป็น[]หรือ[[]])?
Erik the Outgolfer

ฉันมีความสุขกับพฤติกรรมที่ไม่ได้กำหนดไว้ในอินพุตว่าง
jnfnt

คำตอบ:



3

APL (Dyalog Classic) , 84 80 77 76 74 66 61 ไบต์

{⍵⌷⍨{⍵,⍨⊃⍋(1a⌷⍨⊃⍵),⍪⍺⌷a}⍣d/⊃⍸a=d←⌈/512|,a←⌊.+⍨⍣≡9*⍨2⌊⍵+.≠⍉⍵}

ลองออนไลน์!

อินพุตและเอาต์พุตเป็นเมทริกซ์อักขระ

⍵+.≠⍉⍵ เมทริกซ์ของระยะห่างระหว่างคำพูดที่มีลักษณะคล้ายกัน

9*⍨2⌊ปล่อยให้ 0s และ 1s ไม่เปลี่ยนแปลงเปลี่ยน 2+ เป็นจำนวนมาก (512 = 2 9ใช้เป็น "∞")

⌊.+⍨⍣≡ อัลกอริทึมเส้นทางที่สั้นที่สุดของfloyd & warshall

  • ⌊.+เช่นการคูณเมทริกซ์ แต่ใช้min( ) และ+แทน+และ×ตามลำดับ

  • ใช้เมทริกซ์เดียวกันทางซ้ายและขวา

  • ⍣≡ ทำซ้ำจนกระทั่งบรรจบกัน

d←⌈/512|, ความยาวของเส้นทางที่ยาวที่สุด (ไม่ใช่ "∞") ที่กำหนดให้ d

⊃⍸a=มันเชื่อมต่อสองโหนดใดกันลองเรียกมันว่าiและj

{⍵,⍨⊃⍋(1≠a⌷⍨⊃⍵),⍪⍺⌷a}⍣d/ สร้างเส้นทางใหม่

  • { }⍣d/ประเมิน{ }ฟังก์ชั่นdครั้ง หาเรื่องซ้ายเสมอฉัน ARG ด้านขวาเริ่มต้นเป็นjและค่อยๆสะสมโหนดภายในของเส้นทาง

  • (1≠a⌷⍨⊃⍵),⍪⍺⌷a สร้างเมทริกซ์ 2 คอลัมน์ของเวกเตอร์สองตัวนี้:

    • 1≠a⌷⍨⊃⍵ booleans (0 หรือ 1) บ่งชี้ว่าโหนดใดอยู่ที่ระยะทาง 1 ถึงจุดแรกของ

    • ⍺⌷a ระยะทางของโหนดกราฟทั้งหมดถึง

  • ⊃⍋ ดัชนีของแถวที่เล็กที่สุดในพจนานุกรม

  • ⍵,⍨ เสริมเพื่อ

⍵⌷⍨ จัดทำดัชนีคำต้นฉบับด้วยเส้นทาง


2

Python 3 , 225 ไบต์

from itertools import*
def f(a):b=[((p[0],p[-1]),(len(p),p))for i in range(len(a))for p in permutations(a,i+1)if all(sum(q!=r for q,r in zip(*x))<2for x in zip(p,p[1:]))];return max(min(r for q,r in b if x==q)for x,y in b)[1]

ลองออนไลน์!

โดยทั่วไปให้ใช้เส้นทางที่เป็นไปได้ทั้งหมดเก็บเฉพาะเส้นทางที่ถูกต้องจากนั้นผ่านชุดค่าผสมแต่ละชุดเริ่มต้นค้นหาระยะทางเส้นทางต่ำสุดและค้นหาค่าสูงสุด



1

JavaScript (ES6),  195  194 ไบต์

[optimal_length, [optimal_path]]ผลตอบแทน

f=(a,p=[],w=o=[],l=0)=>Object.values(o,o[k=[w,p[0]]]=(o[k]||0)[0]<l?o[k]:[l,p],a.map((v,i)=>w+w&&[...v].map((c,i)=>s-=c!=w[i],s=1)|s||f(a.filter(_=>i--),[...p,v],v,l+1))).sort(([a],[b])=>b-a)[0]

ลองออนไลน์!

อย่างไร?

fow0w1[l,p]pw0w1l

plwpo

o[k = [w, p[0]]] = (o[k] || 0)[0] < l ? o[k] : [l, p]

o

Object.values(o).sort(([a], [b]) => b - a)[0]

(รหัสนี้จะถูกดำเนินการในแต่ละความลึกของการเรียกซ้ำ แต่มีเพียงระดับรากที่สำคัญเท่านั้น)

vw

[...v].map((c, i) => s -= c != w[i], s = 1) | s

v

f(                    //
  a.filter(_ => i--), // remove the i-th word from a[]
  [...p, v],          // append v to p[]
  v,                  // pass v as the last word
  l + 1               // increment the length of the path
)                     //


0

Python 3, 228 ไบต์

def G(w):
    D={A+B:[A,B]if sum(a!=b for a,b in zip(A,B))<2else[0,0]*len(w)for A in w for B in w}
    for k in w:
        for i in w:
            for j in w:
                p=D[i+k]+D[k+j][1:]
                if len(p)<len(D[i+j]):D[i+j]=p
    return max(D.values(),key=len)

ใช้อัลกอริธึม Floyd-Warshall สำหรับเส้นทางที่สั้นที่สุดของทุกคู่จากนั้นใช้สูงสุดเหนือเส้นทางที่พบ

อักขระ 16 ตัวในการใช้งานนี้เป็นแท็บซึ่งเป็นโชคร้าย :(


2
สิ่งนี้ดูเหมือนจะพังเมื่อมีจุดสุดยอดที่ไม่มีขอบของเหตุการณ์เช่น "พิมพ์ G (['กระเป๋า', 'bat', 'cot']))"
jnfnt

เคล็ดลับการเล่นกอล์ฟสำหรับการเยื้อง Python: ใช้ช่องว่างสำหรับระดับแรกแท็บสำหรับที่สองแท็บและช่องว่างสำหรับที่สามแท็บสองแท็บสำหรับสี่และอื่น ๆ
Peter Taylor

1
@PeterTaylor คำแนะนำที่ดี แต่ใช้ได้กับ Python 2 เท่านั้น Python 3 ไม่อนุญาตให้ผสมแท็บกับช่องว่าง
OOBalance

1
อ่าจับได้ดี @jnfnt ตอนนี้ฉันคิดเกี่ยวกับมันใช้งานได้เฉพาะเมื่อเชื่อมต่อกราฟ
rikhavshah
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.