ล้อมรอบผลที่ตามมา


11

บทนำ

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

เป็นทางการมากขึ้นให้uและvเป็นสองสายใด ๆ และk ≥ 0จำนวนเต็ม เราบอกว่าuเป็นksubsequence -wrappingของvถ้ามีดัชนีที่แตกต่างกันเช่นว่าและที่มากที่สุดของดัชนีความพึงพอใจ ซึ่งหมายความว่าสามารถพบได้ในโดยไปจากซ้ายไปขวาเลือกบางส่วนของตัวละครเกี่ยวกับวิธีการและการตัดรอบที่มากที่สุดเท่า (เท่าที่มากที่สุดทำเรตติ้งทั่ว) โปรดทราบว่าไม่มีตัวเลือกใดที่สามารถเลือกได้มากกว่าหนึ่งครั้งแม้กระทั่งหลังการล้อมรอบและการเรียงลำดับการห่อหุ้มนั้นเป็นชุดประกอบสามัญที่เราทุกคนคุ้นเคยi1, i2, ..., ilen(u)u == v[i1] v[i2] ... v[ilen(u)]kijij > ij+1uvkk+1v0

งาน

ปัจจัยการผลิตของคุณมีสองสายที่เป็นตัวเลขไม่ว่างเปล่าuและvและส่งออกของคุณเป็นที่เล็กที่สุดจำนวนเต็มkดังกล่าวว่าuเป็นksubsequence -wrapping vของ หากไม่มีการดังกล่าวมีอยู่แล้วการส่งออกจะเป็นk-1

ตัวอย่าง

พิจารณาปัจจัยการผลิตและu := xyzyxzzxyx v := yxzzazzyxxxyzถ้าเราเริ่มมองหาตัวละครของuในvในแฟชั่นโลภเราจะห่อรอบ 3 ครั้ง:

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

ดังนั้นผลลัพธ์ที่ถูกต้องคือสูงสุด 3 โปรดทราบว่าอักขระซ้ายสุดxถูกเลือกหนึ่งครั้งแล้วละเว้นในการกวาดครั้งที่สองเนื่องจากไม่สามารถใช้ซ้ำได้ อย่างไรก็ตามมีวิธีที่สั้นกว่าโดยมีการล้อมรอบเพียง 2 แบบ:

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

แต่กลับกลายเป็นว่าหนึ่งรอบ (นั่นคือสองเรตติ้ง) 2ไม่เพียงพอดังนั้นการส่งออกที่ถูกต้องคือ

กฎและโบนัส

คุณสามารถเขียนฟังก์ชั่นหรือโปรแกรมเต็มรูปแบบและคุณยังสามารถเปลี่ยนลำดับของอินพุตได้ตามต้องการ จำนวนไบต์ต่ำสุดที่ชนะและช่องโหว่มาตรฐานไม่ได้รับอนุญาต

มีโบนัส -10%สำหรับการคำนวณทุกกรณีทดสอบภายในเวลา 10 วินาทีรวม ฉันจะทดสอบเคสที่ไม่ชัดเจนในเครื่องของฉัน การใช้การอ้างอิงของฉันใน Python ใช้เวลาประมาณ 0.6 วินาที ฉันมีแล็ปท็อปอายุ 7 ปีที่มีซีพียู dual-core 1.86 GHz ซึ่งคุณอาจต้องคำนึงถึง

กรณีทดสอบ

"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
นี่จะเป็นโซลูชันที่ถูกต้องสำหรับตัวอย่างด้วยหรือไม่ มันเป็นวิธีโลภ
orlp

@orlp มันไม่ถูกต้องเพราะอันแรกxถูกใช้ในสามเรตติ้งที่แตกต่างกัน สามารถใช้งานได้เพียงครั้งเดียว
Zgarb

Ahhh ฉันเห็นแล้ว
orlp

คำตอบ:


4

Pyth, 34 ไบต์

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

ฟังก์ชันนี้กำหนดฟังก์ชันgซึ่งรับสองสตริงเป็นพารามิเตอร์ ลองใช้งานออนไลน์: Pyth Compiler / Executor

รหัสนี้ไม่มีประสิทธิภาพมาก len(v)!/(len(v)-len(u))!แต่ก็มีเวลาและความทรงจำความซับซ้อนของ ไม่สามารถแก้ไขกรณีทดสอบที่ยาวกว่าได้ใน 10 วินาที (นอกจากนี้ยังอาจเกิดปัญหาได้เนื่องจากหน่วยความจำของคุณจะหมด)

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 ไบต์

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]

กำหนดเวลาสำหรับกรณีทดสอบทั้งหมด (หมายเหตุ: ข้อโต้แย้งถูกพลิก):

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

มันทำงานอย่างไร (เวอร์ชั่นสั้น): แรงเดรัจฉานง่ายๆที่ใช้เวลาน้อยที่สุดในการใช้อักขระที่ตรงกันและข้ามไป ฉันหยุดการค้นหาเมื่อทำเสร็จ (คืนจำนวนรอบ) หรือเมื่อขี่จักรยานมากกว่าขั้นต่ำสุด (กลับ -1)

บันทึกจำนวนมากเมื่อเทียบกับรุ่นแรกของฉันส่วนใหญ่เป็นเพราะฉันเปลี่ยนจากโปรแกรมเต็มรูปแบบเป็นฟังก์ชั่น

ด้วยความคิดเห็นและระยะห่างที่เหมาะสม golfed Haskell ค่อนข้างอ่านได้:

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

สำหรับการอ้างอิง: เวอร์ชันเก่าโปรแกรมเต็ม 187 ไบต์

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: ทำใหม่โซลูชันของฉัน ตอนนี้เร็วขึ้นและสั้นลง
nimi

ทำงานใน 0.6 วินาทีเมื่อตีความ 0.01s เมื่อรวบรวม
Zgarb

2

JavaScript (ES6) 174 (193 - 10%)

การค้นหาแบบเรียกซ้ำเช่นคำตอบของ @ nimi ทำให้มีการตัดคำเล็กน้อย พื้นที่โซลูชันมีขนาดใหญ่ (เหนือสิ่งอื่นใดสำหรับตัวอย่างสุดท้าย) แต่การตัดการค้นหาที่ min ที่พบในขณะนี้ทำให้เวลาต่ำ แก้ไข 1เพิ่มกรณีทดสอบที่ขาดหายไปย่อให้สั้นลงเล็กน้อย แก้ไข 2ไม่จำเป็นต้องผ่านพารามิเตอร์รอบตัว

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

Ungolfed

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
}

ทดสอบในคอนโซล 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

เอาต์พุต (บรรทัดสุดท้ายคือเวลาดำเนินการเป็นมิลลิวินาที)

["me", "moe"] 0
["พบ", "metro"] -1
["ababa", "abaab"] 1
["abaab", "baabaa"] 1 1
"1c1C1C2B", "1111CCCcB2"] 3
["ย้อนกลับ", "สงวน"] 2
["abcdefg", "gfedcba"] 6
["xyzyxzzxyx", "yxzzazzyxxxyz"] 2
["aasdffdaasdf", "asdfddasdfsdaafsds"] 2
116


ทดสอบกับ Firebug แล้วทำงานใน 175ms บนเครื่องของฉัน
Zgarb

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