Kết quả bao quanh


11

Giới thiệu

Trong thử thách này, nhiệm vụ của bạn là tìm các chuỗi tổng quát của chuỗi. Các chuỗi con không nhất thiết phải liền kề nhau và chúng cũng có thể "quấn quanh" chuỗi, đi qua kết thúc của nó và bắt đầu lại từ đầu. Tuy nhiên, bạn sẽ muốn giảm thiểu số lượng kết thúc tốt đẹp.

Chính thức hơn, hãy để uvlà bất kỳ hai chuỗi, và k ≥ 0một số nguyên. Chúng tôi nói rằng đó ulà một phần ktiếp theo của v, nếu có các chỉ số riêng biệt như vậy , và tại hầu hết các chỉ số đều thỏa mãn . Điều này có nghĩa là có thể được tìm thấy bên trong bằng cách đi từ trái sang phải, chọn một số nhân vật của nó trên đường và quấn quanh nhiều lần (tương đương, thực hiện hầu hết các lần quét ngang ). Lưu ý rằng không có nhân vật nào có thể được chọn nhiều hơn một lần, ngay cả sau khi kết thúc và các phần tiếp theo đó chính xác là các phần tiếp theo thông thường mà chúng ta đều quen thuộc.i1, i2, ..., ilen(u)u == v[i1] v[i2] ... v[ilen(u)]kijij > ij+1uvkk+1v0

Nhiệm vụ

Đầu vào của bạn là hai chuỗi chữ và số không trống uv, và đầu ra của bạn là nhỏ nhất số nguyên knhư vậy mà ulà một kdãy -wrapping của v. Nếu không có như vậy k, đầu ra sẽ được -1.

Thí dụ

Hãy xem xét các đầu vào u := xyzyxzzxyxv := yxzzazzyxxxyz. Nếu chúng ta bắt đầu tìm kiếm các nhân vật của utrong vmột cách tham lam, chúng tôi sẽ quấn quanh 3 lần:

 yxzzazzyxxxyz
>─x─────y────z┐
┌─────────────┘
└y───────x────┐
┌─────────────┘
└──zz─────x─y─┐
┌─────────────┘
└──────────x──>

Do đó, đầu ra chính xác nhiều nhất là 3. Lưu ý cách ký tự ngoài cùng bên trái xđược chọn một lần, và sau đó bỏ qua trong lần quét thứ hai, vì nó không thể được sử dụng lại. Tuy nhiên, tồn tại một phương thức ngắn hơn chỉ với 2 lần bao quanh:

 yxzzazzyxxxyz
>──────────xyz┐
┌─────────────┘
└yxzz────x────┐
┌─────────────┘
└───────y─x───>

Nó chỉ ra rằng một vòng bao quanh (nghĩa là hai lần quét) là không đủ, vì vậy đầu ra chính xác là 2.

Quy tắc và tiền thưởng

Bạn có thể viết một hàm hoặc một chương trình đầy đủ và bạn cũng có thể thay đổi thứ tự của các đầu vào nếu cần. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép.

phần thưởng -10% cho việc tính toán tất cả các trường hợp thử nghiệm trong tổng số dưới 10 giây. Tôi sẽ kiểm tra các trường hợp không rõ ràng trên máy của tôi; việc thực hiện tham chiếu của tôi trong Python mất khoảng 0,6 giây. Tôi có một máy tính xách tay 7 năm tuổi với CPU lõi kép 1,86 GHz, bạn có thể muốn tính đến.

Các trường hợp thử nghiệm

"me" "moe" -> 0
"meet" "metro" -> -1
"ababa" "abaab" -> 1
"abaab" "baabaa" -> 1
"1c1C1C2B" "1111CCCcB2" -> 3
"reverse" "reserved" -> 2
"abcdefg" "gfedcba" -> 6
"xyzyxzzxyx" "yxzzazzyxxxyz" -> 2
"aasdffdaasdf" "asdfddasdfsdaafsds" -> 2

1
Đây cũng sẽ là một giải pháp hợp lệ cho ví dụ? Đó là một cách tiếp cận tham lam.
orlp

@orlp Không hợp lệ, vì lần đầu tiên xđược sử dụng trong ba lần quét riêng biệt. Nó chỉ có thể được sử dụng một lần.
Zgarb

Ahhh, tôi thấy bây giờ.
orlp

Câu trả lời:


4

Bình thường, 34 byte

Mh+Smssm>.ukC,dtdfqGsm@HkT.PUHlG_1

Điều này xác định một hàm g, lấy hai chuỗi làm tham số. Dùng thử trực tuyến: Trình biên dịch / thực thi Pyth

Mã này rất không hiệu quả. Nó có một thời gian và bộ nhớ phức tạp len(v)!/(len(v)-len(u))!. Nó không thể giải quyết các trường hợp thử nghiệm dài hơn trong vòng dưới 10 giây. (Nó cũng sẽ bị sập rất có thể, vì nó sẽ hết bộ nhớ.)

M                                    define g(G, H): return _
                          .PUHlG        all permutations of [0, 1, ..., len(H)-1] of length len(G)
                 fqGsm@HkT              filter the permutations which form the string G
    mssm>.ukC,dtd                       compute the number of wraps for each of the remaining permutations
  +S                            _1      sort the numbers and append -1
 h                                      return the first element

4

Haskell, 160 * 0,9 = 144 byte

a#(-1)=a
a#b=min a b
f y=w(y++" ")0$length y
w _ n _[]=n
w(c:d)n o g@(a:b)|n>o=(-1)|a==c=z#w y n z g|c==' '=w y(n+1)o g|1<2=w y n o g where z=w d n o b;y=d++[c]

Thời gian cho tất cả các trường hợp thử nghiệm (lưu ý: đối số được lật):

*Main> map (uncurry f) [
             ("moe", "me"),
             ("metro", "meet"),
             ("abaab", "ababa"),
             ("baabaa", "abaab"),
             ("1111CCCcB2", "1c1C1C2B"),
             ("reserved", "reverse"),
             ("gfedcba", "abcdefg"),
             ("yxzzazzyxxxyz", "xyzyxzzxyx"),
             ("asdfddasdfsdaafsds", "aasdffdaasdf")]
[0,-1,1,1,3,2,6,2,2]
(0.08 secs, 25794240 bytes)

Cách thức hoạt động (phiên bản ngắn): lực lượng vũ phu đơn giản sử dụng tối thiểu việc sử dụng một nhân vật phù hợp và bỏ qua nó. Tôi dừng tìm kiếm khi kết thúc (trả về số chu kỳ) hoặc khi đạp xe nhiều hơn mức tối thiểu cho đến nay (trả về -1).

Đã lưu rất nhiều byte so với phiên bản đầu tiên của tôi, chủ yếu là do tôi đã chuyển từ một chương trình đầy đủ sang một chức năng.

Với một số ý kiến ​​và khoảng cách thích hợp, Haskell có thể đọc được:

-- a minimum function that ignores a -1 in the right argument to prevent
-- "not solvable" cases in parts of the recursive search to dominate low numbers
-- of solvable parts. If the case isn't solvabale at all, both arguments are
-- -1 and are carried on.
a # (-1) = a
a # b    = min a b

-- the main function f calls the worker funktion w with arguments
-- * the string to search in (STSI), appended by a space to detect cycles
-- * the number of cycles so far
-- * the minimum of cycles needed so far, starting with the length of STSI
-- * the string to search for (STSF) (partial applied away and therefore invisible)
f y = w (y++" ") 0 (length y)

-- the worker function 
w _ n _ [] = n          -- base case: if STSF is empty the work is done and the 
                        -- number of cycles is returned

w (c:d) n o g@(a:b)     -- "c" is first char of STSI, "d" the rest
                        -- "n" number of cycles, "o" minimum of cycles so far
                        -- "g" is the whole STSF, "a" the 1st char, "b" the rest
  | n>o    = (-1)             -- if current cycle is more than a previous result,
                              -- indicate failure
  | a==c   = z # w y n z g    -- if there's a character match, take the min of
                              -- using it and skipping it
  | c==' ' = w y (n+1) o g    -- cycle detected, repeat and adjust n
  | 1<2    = w y n o g        -- otherwise try next char in STSI

  where                 -- just some golfing: short names for common subexpressions
  z = w d n o b;        -- number of cycles if a matching char is used
  y = d ++ [c]          -- rotated STSI

Để tham khảo: phiên bản cũ, chương trình đầy đủ, 187 byte

main=interact$show.f.lines
a#(-1)=a
a#b=min a b
f[x,y]=w x(y++" ")0 0
w[]_ n _=n
w g@(a:b)(c:d)n m|a==c=w b d n 1#y|c==' '&&m==1=w g(d++" ")(n+1)0|c==' '=(-1)|1<2=y where y=w g(d++[c])n m

@Zgarb: làm lại giải pháp của tôi. Bây giờ nhanh hơn và ngắn hơn.
nimi

Chạy trong 0,6 giây khi được giải thích, 0,01 giây khi được biên dịch.
Zgarb

2

JavaScript (ES6) 174 (193 - 10%)

Tìm kiếm đệ quy, như câu trả lời của @ nimi, giữ cho kết thúc tốt đẹp. Không gian giải pháp là lớn (trên hết là ví dụ cuối cùng) nhưng việc cắt giảm tìm kiếm ở mức tối thiểu hiện được tìm thấy giữ cho thời gian thấp. Chỉnh sửa 1 Thêm trường hợp kiểm tra bị thiếu, rút ​​ngắn một chút Chỉnh sửa 2 Không cần vượt qua param w xung quanh, nó đã được sửa

K=(w,s,x)=>
  ~-(R=(r,l,p=0,q=1,z=w[p],i=0)=>
  {
    if(z&&!(q>x)){
      if(~(r+l).indexOf(z))
        for(t=l?R(l+r,'',p,q+1):x;x<t?0:x=t,i=~r.indexOf(z,-i);)
          t=R(r.slice(-i),l+r.slice(0,~i),p+1,q);
      q=x
    }
    return q
  })(s,'')

Ung dung

K=(word, astring)=>
{
  var minWraps // undefined at first. All numeric comparison with undefined give false 
  var R=(right, left, pos, wraps)=>
  {
    var cur = word[pos]
    var i,t;
    if (! cur) // when all chars of word are managed
      return wraps;
    if (wraps > minWraps) // over the minimum wrap count already found, stop search
      return wraps; 
    if ( (right+left).indexOf(cur) < 0 ) // if the current char is not found in the remaining part of the string
      return minWraps; // return the current min, could still be undefined (that means 'no way')
    if ( left ) // if there is a left part, try a wrapping search with the current char
    {
      t = R(left+right, '', pos, wraps+1)
      if ( !(minWraps < t)) minWraps = t; // set current min if t is less than current min or current min is still undefined
    }
    // find all occurrences of current char in the remaining part
    // for each occurrence, start a recursive search for the next char
    for(i = 0; (i = right.indexOf(cur, i)) >= 0; i++)
    {
      var passed = right.slice(0,i) // the passed chars go in the left part
      var rest = right.slice(i+1) 
      t = R(rest, left+passed, pos+1, wraps) // try next char in the remaining part, no wrap
      if ( !(minWraps < t)) minWraps = t; // set current min if t is less than current min or current min is still undefined
    }
    return minWraps
  }
  var result = R(astring, '', 0, 1) // start with right=string and left empty
  return ~-result; // decrement. convert undefined to -1
}

Kiểm tra trong bảng điều khiển Firefox / FireBug

time=~new Date;
[['me','moe']
,['meet','metro']
,['ababa','abaab']
,['abaab','baabaa']
,['1c1C1C2B','1111CCCcB2']
,['reverse','reserved']
,['abcdefg','gfedcba']
,['xyzyxzzxyx','yxzzazzyxxxyz']
,['aasdffdaasdf','asdfddasdfsdaafsds']]
.forEach(s=>console.log(s,r=K(...s)))
time-=~new Date

Đầu ra (dòng cuối cùng là thời gian thực hiện tính bằng ms)

["tôi", "moe"] 0
["gặp", "metro"] -1
["ababa", "abaab"] 1
["abaab", "baabaa"] 1
["1c1C1C2B", "1111CCCcB2"] 3
[ "đảo ngược", "dành riêng"] 2
[ "abcdefg", "gfedcba"] 6
[ "xyzyxzzxyx", "yxzzazzyxxxyz"] 2
[ "aasdffdaasdf", "asdfddasdfsdaafsds"] 2
116


Đã thử nghiệm với Fireorms, chạy trong 175ms trên máy của tôi.
Zgarb

@Zgarb sau đó có chỗ để cải tiến: Tôi sẽ cố gắng làm cho nó chậm hơn và ngắn hơn
edc65
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.