Khả năng tiếp cận từ thay đổi


13

Word changer là một trò chơi trong đó bạn đang cố gắng biến một từ này thành một từ khác thông qua các chỉnh sửa một ký tự, với mỗi bước là một từ riêng. Đối với thử thách này, các chỉnh sửa có thể là thay thế, chèn thêm hoặc xóa. Ví dụ: CHIẾN THẮNG → LOSER có thể được thực hiện với tuyến đường này (có thể có những người khác):

WINNER
DINNER
DINER
DINE
LINE
LONE
LOSE
LOSER

Phrased cách khác, bạn phải có thể đạt được một từ từ khác chỉ thông qua các từ khác ở khoảng cách Levenshtein là 1 mỗi lần.

Mã hóa

Bạn sẽ được cung cấp một danh sách từ và hai từ và bạn phải xuất một tuyến hợp lệ từ một từ này sang một từ khác nếu một tuyến tồn tại hoặc một giá trị không đổi khác biệt hoặc hành vi nhất quán nếu không có tuyến nào tồn tại.

  • Bạn có thể cho rằng các từ đầu vào đều nằm trong danh sách từ
  • Danh sách từ có thể được thực hiện thông qua bất kỳ định dạng phẳng thuận tiện.
    • Danh sách, bộ, thử, chuỗi được phân tách bằng dấu cách và các tệp được phân tách bằng dòng đều hợp lệ (ví dụ), nhưng một biểu đồ được tính toán trước của kề kề Levenshtein thì không.
  • Lộ trình đầu ra phải bao gồm cả các từ đầu vào, nhưng bắt đầu và kết thúc không thành vấn đề.
  • Nếu không tìm thấy tuyến đường nào, bạn có thể xuất ra một hằng số cụ thể, giá trị giả, danh sách trống, ném ngoại lệ, thoát với mã khác không hoặc bất kỳ hành vi nào xảy ra trong thời gian hữu hạn.
  • Tuyến đường không cần phải tối ưu và không có yêu cầu về tuyến đường nào nên được thực hiện
  • Độ phức tạp tính toán không thành vấn đề, tuy nhiên chương trình của bạn phải được đảm bảo chắc chắn để chấm dứt trong một khoảng thời gian hữu hạn. (ngay cả khi nó chạy vượt khỏi cái chết nhiệt của vũ trụ)
  • Bạn có thể giả sử tất cả các từ hoàn toàn bao gồm các chữ cái trong cùng một trường hợp

Ví dụ trường hợp kiểm tra

  • CÁT → DOG; [CAT, DOG, COG, COT, FROG, GROG, BOG]
    • CAT, COT, COG, DOG
  • TẮM → VÒI; [TẮM, SHOWER, Hath, HAT, BAT, SAT, SAW, SOW, SHOW, CÁCH]
    • Không tìm thấy tuyến đường
  • BREAK → CỐ ĐỊNH; [BREAK, FIX, BEAK, BREAD, READ, BEAD, RED, BED, BAD, BID, FAD, FAX]
    • BREAK, BREAD, BEAD, BAD, FAD, FAX, CỐ ĐỊNH
  • XÂY DỰNG → KHAI THÁC; [BUILD, DESTROY, BUILT, GUILT, GUILD, GILD, GILL, BILL, DILL, FILL, DESTRATION, CẤU TRÚC, XÂY DỰNG]
    • Không tìm thấy tuyến đường
  • THẺ → BAN; [THẺ, BAN, BARD]
    • THẺ, BARD, BAN
  • DEMON → ANGEL; [DEMON, ANGEL]
    • Không tìm thấy tuyến đường
  • CUỐI → TRẢ TIỀN; [LAST, PAST, BLAST, CAST, BLACK, GHOST, POST, BOAST]
    • QUÁ KHỨ VỪA QUA
  • XÁC NHẬN → XÓA; Danh sách từ này
    • CHỨNG MINH, KHÔNG BAO GIỜ, PHÁT HIỆN, INBENT, UNBENT, UNBEND, UNBIND, UNKIND, UNKING, INKING, IRKING, DIRKING, DARKING, DARLING, ARLING, AILING, SIRING, SERING, SERING, SERING, SERER XÓA BỎ


1
Chúng ta có thể đưa ra một danh sách các tuyến hợp lệ hay nên là một tuyến?
Emigna

@Emigna bất kỳ tuyến đường nào cũng được. Như tôi đã đề cập "Tuyến đường không cần phải tối ưu"
Beefster

Chúng ta có cần bao gồm từ bắt đầu và kết thúc trong đầu ra không? Các tuyến đường sẽ luôn luôn bắt đầu và kết thúc như nhau!
Bạch tuộc ma thuật Urn

1
@MagicOctopusUrn "Tuyến đầu ra phải bao gồm cả các từ đầu vào, nhưng bắt đầu và kết thúc không thành vấn đề."
Beefster

Câu trả lời:


5

05AB1E , 23 21 20 byte

In một danh sách các tuyến hợp lệ.
Đã lưu 2 byte nhờ Kevin Cruijssen .

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

Hãy thử trực tuyến!


Bạn có thể lưu 2 byte bằng cách thay đổi Dævyœ«}thành 怜€` . (Không chắc tại sao cả hai bản đồ riêng biệt đều hoạt động tốt, nhưng æεœ`}không btw, nhưng dù sao nó cũng có cùng số byte.)
Kevin Cruijssen

Quá xấu sản phẩm của []1thay vì 0(không quá ngạc nhiên, mặc dù) hoặc một kiểm tra tương đương với danh sách trống rõ ràng kết quả trong một danh sách trống thay vì 0(cái này tôi thấy như một lỗi ..) .. Nếu không, bạn có thể kết hợp bộ lọc và find_first để lưu một byte khác:怜€`.Δü.LPy¬²Qsθ³QP
Kevin Cruijssen

@KevinCruijssen: Cảm ơn! Không chắc tại sao tôi không nghĩ đến việc sử dụng . Tôi nghĩ rằng kết quả kiểm tra bằng nhau trong một danh sách trống do vector hóa. Có lẽ nên có một trường hợp đặc biệt cho danh sách trống, nhưng có lẽ điều đó sẽ bất ngờ trong các trường hợp khác.
Emigna

1
Có một cái gì đó như thế này hoạt động cho 17: Hãy thử trực tuyến!
Bạch tuộc ma thuật Urn

1
@MagicOctopusUrn: Thật không may, chúng tôi cần bao gồm tất cả các từ của đường dẫn trong đầu ra.
Emigna

4

JavaScript (V8) ,  177  176 byte

Đưa đầu vào là (target)(source, list). In tất cả các tuyến đường có thể. Hoặc không in gì nếu không có giải pháp.

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))

Hãy thử trực tuyến!

Đã bình luận

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 byte

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)

Hãy thử trực tuyến!

Lấy hai từ và một tập hợp các từ làm đầu vào; trả về một tuyến (không tối ưu) nếu một tồn tại dưới dạng một danh sách các chuỗi, nếu không thì trả về Sai.

Đoạn này:

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

Truenếu và chỉ khi a==whoặc acó khoảng cách Levenshtein 1từ w.



2

Python 2 , 163 byte

Nếu một tuyến đường được tìm thấy, nó là đầu ra cho thiết bị lỗi chuẩn và chương trình thoát với mã thoát 1.
Nếu không có tuyến đường, không có đầu ra và chương trình kết thúc với mã thoát 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:]]

Hãy thử trực tuyến!


1

Python 3 , 217 214 212 201 byte

-11 byte thanx đến một gợi ý từ xnor

d=lambda a,b:min(d(a[1:],b[1:])+(a[0]!=b[0]),d(a[1:],b)+1,d(a,b[1:])+1)if b>""<a else len(a+b)
def g(a,b,l,p=[]):
	if a==b:yield[a]+p
	for c in(a!=b)*l:
		if(c in p)+d(a,c)==1:yield from g(c,b,l,[a]+p)

Hãy thử trực tuyến!


0

Thạch , 38 byte

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

Hãy thử trực tuyến!

Một chương trình đầy đủ chấp nhận ba đối số. Đầu tiên là từ bắt đầu và được cung cấp dưới dạng [["START"]]. Đối số thứ hai là từ cuối cùng, được cung cấp dưới dạng "END". Đối số thứ ba là danh sách từ, được cung cấp dưới dạng trích dẫn, các từ được phân tách bằng dấu phẩy.

Chương trình trả về một danh sách các danh sách, với mỗi danh sách đại diện cho một đường dẫn hợp lệ từ đầu đến cuối. Nếu không có tuyến hợp lệ, phản hồi là một danh sách trống.

Trong liên kết TIO, có văn bản chân trang để hiển thị kết quả độc đáo với mỗi từ được phân tách bằng dấu cách và mỗi danh sách các từ được phân tách bằng dòng mới. Nếu một bản in đại diện danh sách cơ bản được ưa thích, điều này có thể được thực hiện như ÇŒṘ.

Không giống như 05ABIE, không có tích hợp khoảng cách Levenshtein, vì vậy chương trình này so sánh các tiền tố với một ký tự bị thiếu, hơi giống với giải pháp của @ ChasBrown , mặc dù có một nút xoắn Jelly.

Giải trình

Liên kết người trợ giúp: liên kết đơn âm có danh sách các từ và trả về danh sách các danh sách mở rộng có thể hoặc danh sách trống nếu không thể mở rộng thêm

⁵ḟ                      | 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)

Liên kết chính

              €         | 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 byte

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])

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.