การเข้าถึงของ Word Changer


13

Word changer เป็นเกมที่คุณพยายามเปลี่ยนคำหนึ่งไปเป็นอีกคำหนึ่งผ่านการแก้ไขอักขระเดียวโดยแต่ละขั้นตอนจะเป็นคำของตัวเอง สำหรับความท้าทายนี้การแก้ไขอาจเป็นการแทนที่การแทรกหรือการลบ ตัวอย่างเช่น WINNER → LOSER สามารถทำได้กับเส้นทางนี้ (อาจมีบางอย่าง):

WINNER
DINNER
DINER
DINE
LINE
LONE
LOSE
LOSER

อีกวิธีหนึ่งคุณต้องสามารถเข้าถึงหนึ่งคำจากอีกคำหนึ่งโดยใช้คำอื่นที่ระยะทาง 1 ของ Levenshtein

การเข้ารหัส

คุณจะได้รับรายการคำและสองคำและคุณจะต้องออกเส้นทางที่ถูกต้องจากคำหนึ่งไปยังอีกหากเส้นทางมีอยู่หรือค่าคงที่ที่แตกต่างกันหรือพฤติกรรมที่สอดคล้องกันหากไม่มีเส้นทาง

  • คุณอาจสมมติว่าคำที่ป้อนมีทั้งในรายการคำ
  • รายการคำสามารถใช้ผ่านรูปแบบแบน ๆ ที่สะดวก
    • รายการ, ชุด, พยายาม, สตริงที่คั่นด้วยช่องว่างและไฟล์ที่คั่นด้วยเส้นจะใช้ได้ทั้งหมด (ตัวอย่างเช่น) แต่กราฟที่คำนวณล่วงหน้าของ Levenshtein adjacency ไม่ใช่
  • เส้นทางขาออกควรมีทั้งคำที่ป้อนข้อมูล แต่สิ่งที่เริ่มต้นและสิ้นสุดนั้นไม่สำคัญ
  • หากไม่พบเส้นทางคุณสามารถส่งออกค่าคงที่เฉพาะเจาะจงค่าเท็จรายการว่างเปล่าโยนข้อยกเว้นออกด้วยรหัสที่ไม่ใช่ศูนย์หรือพฤติกรรมอื่น ๆ ที่เกิดขึ้นในเวลา จำกัด
  • เส้นทางไม่จำเป็นต้องมีประสิทธิภาพสูงสุดและไม่มีข้อกำหนดว่าควรใช้เส้นทางใด
  • ความซับซ้อนในการคำนวณไม่สำคัญว่าอย่างไรโปรแกรมของคุณจะต้องได้รับการรับรองอย่างแน่นอนว่าจะยุติในเวลาอัน จำกัด (แม้ว่ามันจะวิ่งหนีความร้อนของเอกภพ)
  • คุณอาจถือว่าคำทั้งหมดประกอบด้วยตัวอักษรทั้งหมดในกรณีเดียวกัน

ตัวอย่างกรณีทดสอบ

  • CAT → DOG; [CAT, DOG, COG, COT, FROG, GROG, BOG]
    • CAT, COT, COG, DOG
  • อาบน้ำ→อาบน้ำ; [BATH, SHOWER, HAT, HAT, BAT, SAT, SAW, SOW, SHOW, HOW]
    • ไม่พบเส้นทาง
  • BREAK →แก้ไข; [BREAK, FIX, BEAK, BREAD, READ, BEAD, RED, BED, BAD, BID, FAD, FAX]
    • BREAK, BREAD, BEAD, BAD, FAD, FAX, FIX
  • BUILD → DESTROY; [สร้าง, ทำลาย, สร้าง, สร้าง, สร้างรายได้, สร้างรายได้, สร้างรายได้, สร้างรายได้, สร้างโครงสร้าง, สร้างโครงสร้าง]
    • ไม่พบเส้นทาง
  • บัตร→คณะกรรมการ; [บัตรคณะกรรมการ]
    • บัตรคณะกรรมการ
  • DEMON → ANGEL; [DEMON, ANGEL]
    • ไม่พบเส้นทาง
  • LAST → PAST; [LAST, PAST, BLAST, CAST, BLACK, GHOST, POST, BOAST]
    • LAST, PAST
  • INSERT → DELETE; รายการคำนี้
    • INSERT, INVERT, INBENT, INBENT, UNBENT, UNBIND, UNBIND, UNKIND, UNKING, CER, DATE, IRKING, DERKING, SEARING, SERING, SERER ลบ


1
เราสามารถแสดงรายการเส้นทางที่ถูกต้องหรือควรเป็นเส้นทางเดียวได้หรือไม่?
Emigna

@Emigna เส้นทางใด ๆ ที่จะทำ ดังที่ฉันกล่าวถึง "เส้นทางไม่จำเป็นต้องดีที่สุด"
Beefster

เราจำเป็นต้องรวมคำเริ่มต้นและคำลงท้ายในผลลัพธ์หรือไม่? เส้นทางจะเริ่มต้นและสิ้นสุดเหมือนเดิมเสมอ!
Magic Octopus Urn

1
@MagicOctopusUrn "เส้นทางการส่งออกควรมีทั้งคำที่ป้อน แต่คำที่เริ่มต้นและสิ้นสุดไม่สำคัญ"
Beefster

คำตอบ:


5

05AB1E , 23 21 20 ไบต์

พิมพ์รายการเส้นทางที่ถูกต้อง
ที่บันทึกไว้ 2 ไบต์ต้องขอบคุณเควิน Cruijssen

怜€`ʒü.LP}ʒ¬²Qsθ³Q*

ลองออนไลน์!


คุณสามารถบันทึก 2 ไบต์โดยการเปลี่ยนไปDævyœ«} 怜€` (ไม่แน่ใจว่าทำไมทั้งสองแผนที่แยกกันทำงานได้ดี แต่æεœ`}ไม่ btw แต่มันนับเป็นไบต์เดียวกันอยู่ดี)
Kevin Cruijssen

น่าเสียดายที่ผลิตภัณฑ์ของ[]คือ1แทนที่จะเป็น0(ไม่น่าแปลกใจเกินไป) หรือว่าการตรวจสอบที่เท่าเทียมกันกับรายการว่างเปล่าจะส่งผลให้เกิดรายการที่ว่างเปล่าแทน0(อันนี้ฉันเห็นว่าเป็นข้อผิดพลาด .. ) .. มิฉะนั้นคุณอาจรวมกัน ตัวกรองและ find_first บันทึกไบต์อื่น:怜€`.Δü.LPy¬²Qsθ³QP
Kevin Cruijssen

@KevinCruijssen: ขอบคุณ! ไม่แน่ใจว่าทำไมผมไม่ได้คิดว่าการใช้ ฉันคิดว่าผลการตรวจสอบเท่ากันในรายการที่ว่างเปล่าเนื่องจาก vectorization อาจจะมีกรณีพิเศษสำหรับรายการว่างเปล่า แต่อาจจะเป็นกรณีที่ไม่คาดคิดในกรณีอื่น ๆ
Emigna

1
ใช้งานได้กับ 17: ลองออนไลน์ได้ไหม!
Magic Octopus Urn

1
@MagicOctopusUrn: น่าเสียดายที่เราต้องรวมทุกคำของเส้นทางในผลลัพธ์
Emigna

4

JavaScript (V8) ,  177  176 ไบต์

(target)(source, list)จะเข้าเป็น พิมพ์เส้นทางที่เป็นไปได้ทั้งหมด หรือพิมพ์อะไรเลยถ้าไม่มีวิธีแก้ไข

t=>F=(s,l,p=[],d)=>s==t?print(p):l.map((S,i)=>(g=(m,n)=>m*n?1+Math.min(g(m-1,n),g(m,--n),g(--m,n)-(S[m]==s[n])):m+n)(S.length,s.length)^d||F(S,L=[...l],[...p,L.splice(i,1)],1))

ลองออนไลน์!

แสดงความคิดเห็น

t =>                            // t = target string
F = (                           // F is a recursive function taking:
  s,                            //   s = source string
  l,                            //   l[] = list of words
  p = [],                       //   p[] = path
  d                             //   d = expected Levenshtein distance between s and the
) =>                            //       next word (initially undefined, so coerced to 0)
  s == t ?                      // if s is equal to t:
    print(p)                    //   stop recursion and print the path
  :                             // else:
    l.map((S, i) =>             //   for each word S at index i in l[]:
      ( g =                     //     g = recursive function computing the Levenshtein
        (m, n) =>               //         distance between S and s
        m * n ?                 //       if both m and n are not equal to 0:
          1 + Math.min(         //         add 1 to the result + the minimum of:
            g(m - 1, n),        //           g(m - 1, n)
            g(m, --n),          //           g(m, n - 1)
            g(--m, n) -         //           g(m - 1, n - 1), minus 1 if ...
            (S[m] == s[n])      //           ... S[m - 1] is equal to s[n - 1]
          )                     //         end of Math.min()
        :                       //       else:
          m + n                 //         return either m or n
      )(S.length, s.length)     //     initial call to g with m = S.length, n = s.length
      ^ d ||                    //     unless the distance is not equal to d,
      F(                        //     do a recursive call to F with:
        S,                      //       the new source string S
        L = [...l],             //       a copy L[] of l[]
        [...p, L.splice(i, 1)], //       the updated path (removes S from L[])
        1                       //       an expected distance of 1
      )                         //     end of recursive call
    )                           //   end of map()


3

Python 2 , 155 ไบต์

f=lambda a,b,W,r=[]:a==b and r+[a]or reduce(lambda q,w:q or any({a,a[:i]+a[i+1:]}&{w,w[:i]+w[i+1:]}for i in range(len(a+w)))and f(w,b,W-{a},r+[a]),W-{a},0)

ลองออนไลน์!

ใช้สองคำและชุดคำเป็นอินพุต ส่งคืนเส้นทาง (ไม่เหมาะ) หากมีอยู่ในรายการสตริงมิฉะนั้นจะคืนค่า False

ส่วนนี้:

any({a,a[:i]+a[i+1:]}&{w,w[:i]+w[i+1:]}for i in range(len(a+w)))

คือTrueถ้าหากว่าa==wหรือaมี Levenshtein ระยะทางของจาก1w



2

Python 2 , 163 ไบต์

หากพบเส้นทางจะถูกส่งออกไปยัง stderr และโปรแกรมออกจากด้วยรหัสทางออก 1
หากไม่มีเส้นทางจะไม่มีผลลัพธ์และโปรแกรมจะยุติด้วยรหัสทางออก 0

s,e,d=input();r=[[s]]
for x in r:t=x[-1];t==e>exit(x);r+=[x+[w]for w in d-set(x)for a,b in(t,w),(w,t)for i in range(len(b)*2)if a==b[:i/2]+a[i/2:][:i%2]+b[i/2+1:]]

ลองออนไลน์!



0

เยลลี่ , 38 ไบต์

⁵ḟ,€0ị$ṭ¹-Ƥ$€e€/ẸƊƇḢ€
Wṭ@ⱮÇßƊe@⁴oṆƲ?€Ẏ

ลองออนไลน์!

โปรแกรมเต็มรูปแบบยอมรับสามข้อโต้แย้ง [["START"]]ครั้งแรกเป็นคำที่เริ่มต้นและจะจัดเป็น "END"อาร์กิวเมนต์ที่สองเป็นคำสุดท้ายที่จัดเป็น อาร์กิวเมนต์ที่สามคือรายการคำที่ระบุเป็นคำที่คั่นด้วยเครื่องหมายจุลภาค

โปรแกรมส่งคืนรายการของรายการโดยแต่ละรายการแสดงเส้นทางที่ถูกต้องตั้งแต่ต้นจนจบ หากไม่มีเส้นทางที่ถูกต้องการตอบสนองจะเป็นรายการว่างเปล่า

ในลิงก์ TIO จะมีข้อความส่วนท้ายที่จะแสดงผลลัพธ์ได้ดีเมื่อแต่ละคำคั่นด้วยช่องว่างและแต่ละรายการของคำที่คั่นด้วยบรรทัดใหม่ ÇŒṘถ้าพิมพ์ออกมาเป็นตัวแทนรายการต้นแบบที่มีการแนะนำนี้อาจจะทำตาม

ซึ่งแตกต่างจาก 05ABIE ไม่มีระยะทางในตัวของ Levenshtein ดังนั้นโปรแกรมนี้จึงเปรียบเทียบตัว outfix กับอักขระตัวเดียวที่ขาดหายไปซึ่งคล้ายกับวิธีแก้ปัญหาของ @ ChasBrownแม้ว่าจะมี Jelly Twist

คำอธิบาย

ลิงค์ตัวช่วย: ลิงก์แบบ monadic ที่รับรายการคำและส่งคืนรายการของรายการแบบขยายที่เป็นไปได้หรือรายการเปล่าหากไม่สามารถขยายเพิ่มเติมได้

⁵ḟ                      | Filter the word list to remove words already used
  ,€0ị$                 | Pair each word with the last word in the current path
                  ƊƇ    | Filter these pairs such that
              e€/Ẹ      |   there exists any
       ṭ¹-Ƥ$€           |   match between the original words or any outfix with a single character removed
                    Ḣ€  | Take the first word of each of these pairs (i.e. the possible extensions of the route)

ลิงค์หลัก

              €         | For each of the current paths
            Ʋ?          | If:
       e@⁴              |   The path contains the end word
          oṆ            |   Or the path is empty (i.e. could not be extended)
W                       | Return the path wrapped in a list (which will be stripped by the final Ẏ)
 ṭ@ⱮÇ                   | Otherwise, look for possible extensions using the helper link, and add onto the end of the path
     ßƊ                 | And then feed all of these paths back through this link
               Ẏ        | Strip back one layer of lists (needed because each recursion nests the path one list deeper)

0

Swift 4.2 / Xcode 10.2.1 , 387 ไบต์

func d(l:String,m:String)->Bool{return (0..<l.count).contains{var c=l;c.remove(at:c.index(c.startIndex,offsetBy:$0));return c==m}};func f(r:[String])->[String]{if b==r.last!{return r};return w.lazy.map{!r.contains($0)&&(d(l:r.last!,m:$0)||d(l:$0,m:r.last!)||(r.last!.count==$0.count&&zip(r.last!,$0).filter{$0 != $1}.count==1)) ? f(r:r+[$0]):[]}.first{!$0.isEmpty} ?? []};return f(r:[a])

ลองออนไลน์!

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