ฉันไม่ชอบการเปลี่ยนแปลง!


19

การป้อนข้อมูล:

สองสายที่ไม่มีบรรทัดใหม่หรือช่องว่าง

เอาท์พุท:

ทั้งสองสายการป้อนข้อมูลบนเส้นที่แยกต่างหากที่มีช่องว่างในกรณีที่จำเป็นหนึ่งในสองสาย และสายที่สามกับตัวละครA, R, Mและคิดเป็นเพิ่ม , ลบออก , การแก้ไขและเปลี่ยนแปลง

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

ตัวอย่าง:

สมมติว่าสตริงอินพุตเป็นABCDEFและAFBECDจากนั้นผลลัพธ์จะเป็น:

A B CDEF
AFBECD  
 A A  RR

ต่อไปนี้เป็นตัวอย่างเอาต์พุตที่ไม่ถูกต้องอื่น ๆ ที่เป็นไปได้ (และมีอีกมาก):

ABCDEF
AFBECD
 MMMMM

A BCDEF
AFBECD 
 A MMMR

AB CDEF
AFBECD 
 MAMMMR

ABC DEF
AFBECD 
 MMAMMR

ABC  DEF
AFBECD  
 MMAA RR

ABCDEF 
AFB ECD
 MMR MA

 AB CDEF   // This doesn't make much sense,
AFBECD     // but it's to show leading spaces are also allowed
AM A  RR

สิ่งเหล่านี้ไม่มีการเปลี่ยนแปลงเพียงสี่อย่างเท่านั้นดังนั้นA B CDEF\nAFBECD \n A A RRผลลัพธ์ที่ถูกต้องสำหรับความท้าทายนี้

กฏท้าทาย:

  • คุณสามารถสมมติว่าสายป้อนข้อมูลจะไม่มีบรรทัดใหม่หรือช่องว่างใด ๆ
  • สตริงอินพุตสองสตริงมีความยาวต่างกัน
  • หนึ่งในสองสายอินพุตควรยังคงเป็นเช่นยกเว้นช่องว่างชั้นนำ / ต่อท้ายตัวเลือก
  • หากภาษาของคุณไม่รองรับอะไรนอกจาก ASCII คุณสามารถสมมติว่าการป้อนข้อมูลจะมีเฉพาะอักขระ ASCII ที่พิมพ์ได้
  • รูปแบบอินพุตและเอาต์พุตมีความยืดหยุ่น คุณสามารถมีสาม Strings ที่แยกกันอาร์เรย์สตริงสตริงเดี่ยวที่มีบรรทัดใหม่อาร์เรย์อักขระ 2D และอื่น ๆ
  • คุณได้รับอนุญาตให้ใช้อย่างอื่นแทนARMแต่ระบุสิ่งที่คุณใช้ (เช่น123หรือabc.อื่น ๆ )
  • หากมีเอาต์พุตที่ถูกต้องมากกว่าหนึ่งรายการที่มีจำนวนการเปลี่ยนแปลงเท่ากัน ( ARM) คุณสามารถเลือกว่าจะเอาท์พุทที่เป็นไปได้อย่างใดอย่างหนึ่งหรือทั้งหมด
  • ช่องว่างนำหน้าและต่อท้ายเป็นตัวเลือก:

    A B CDEF
    AFBECD
     A A  RR
    

    หรือ

    "A B CDEF\nAFBECD\n A A  RR"
                     ^
                     Note there are no spaces here
    

กฎทั่วไป:

  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ
    อย่าปล่อยให้ภาษาที่ใช้รหัสกอล์ฟกีดกันคุณจากการโพสต์คำตอบด้วยภาษาที่ไม่ codegolfing พยายามหาคำตอบสั้น ๆ ที่เป็นไปได้สำหรับภาษาโปรแกรม 'ใด ๆ '
  • กฎมาตรฐานจะใช้สำหรับคำตอบของคุณดังนั้นคุณจึงได้รับอนุญาตให้ใช้ STDIN / STDOUT ฟังก์ชัน / เมธอดพร้อมพารามิเตอร์ที่เหมาะสมโปรแกรมเต็มรูปแบบ การโทรของคุณ
  • ช่องโหว่เริ่มต้นเป็นสิ่งต้องห้าม
  • หากเป็นไปได้โปรดเพิ่มลิงค์พร้อมทดสอบรหัสของคุณ
  • นอกจากนี้โปรดเพิ่มคำอธิบายหากจำเป็น

กรณีทดสอบ:

In: "ABCDEF" & "AFBECD"

Output (4 changes):
A B CDEF
AFBECD  
 A A  RR                  

In: "This_is_an_example_text" & "This_is_a_test_as_example"

Possible output (13 changes):
This_is_an       _example_text
This_is_a_test_as_example     
         MAAAAAAA        RRRRR

In: "AaAaABBbBBcCcCc" & "abcABCabcABC"

Possible output (10 changes):
AaAaABBbBBcCcCc
 abcABCab cABC 
R MM  MMMR MM R

In: "intf(){longr=java.util.concurrent.ThreadLocalRandom.current().nextLong(10000000000L);returnr>0?r%2:2;}" & "intf(){intr=(int)(Math.random()*10);returnr>0?r%2:2;}"

Possible output (60 changes):
intf(){longr=java.util.concurrent.ThreadLocalRandom.current().nextLong(10000000000L);returnr>0?r%2:2;}
intf(){i ntr=(      i    n      t)(M  ath.r   andom        ()*         10          );returnr>0?r%2:2;}
       MR M  MRRRRRR RRRR RRRRRR MMMRR MMMMRRR     RRRRRRRR  MRRRRRRRRR  RRRRRRRRRR 

In: "ABCDEF" & "XABCDF"

Output (2 changes):
 ABCDEF
XABCD F 
A    R 

In: "abC" & "ABC"

Output (2 changes):
abC
ABC
MM 


หากมีข้อตกลงหลายอย่างที่อยู่ในระยะทางเดียวกันมันตกลงหรือไม่ที่จะส่งออกหนึ่งรายการเท่านั้น
AdmBorkBork

@AdmBorkBork ใช่เพียงหนึ่งในผลลัพธ์ที่เป็นไปได้คือผลลัพธ์ที่ต้องการ (แม้ว่าการส่งออกตัวเลือกที่มีทั้งหมดก็ใช้ได้เช่นกัน) ฉันจะอธิบายเรื่องนี้ในกฏท้าทาย
Kevin Cruijssen

@Arnauld ฉันได้ลบกฎเกี่ยวกับช่องว่างนำหน้าดังนั้นช่องว่างนำหน้าและต่อท้ายจึงเป็นทั้งตัวเลือกและใช้ได้กับบรรทัดที่ไม่ได้แก้ไข (ซึ่งหมายความว่ากรณีทดสอบสุดท้ายในคำตอบของคุณนั้นถูกต้องสมบูรณ์)
Kevin Cruijssen

1
@Ferrybig อ่าโอเคขอบคุณสำหรับคำอธิบาย แต่สำหรับความท้าทายนี้การรองรับ ASCII ที่พิมพ์ได้นั้นเพียงพอแล้ว หากคุณต้องการการสนับสนุนเพิ่มเติมเป็นแขกของฉัน แต่ตราบใดที่มันใช้งานได้ในกรณีทดสอบเนื่องจากฉันตกลงกับพฤติกรรมที่ไม่ได้กำหนดสำหรับกลุ่มแกรฟีนซึ่งประกอบด้วยอักขระมากกว่า 1 ตัว :)
Kevin Cruijssen

คำตอบ:


5

Haskell , 192 181 174 161 158 150 147 143 158 1ไบต์

e@(a:r)&f@(b:s)=snd$maximum[([1|' '<-s!!2],s)|s<-z(z(:))[a:" R",' ':b:"A",a:b:last("M":[" "|a==b])][r&f,e&s,r&s]]
x&y=[x,y,"RA"!!(0^length x)<$x++y]
z=zipWith

ลองออนไลน์! ตัวอย่างการใช้: "ABCDEF" & "AFBECD". ส่งคืนรายการของสามสาย นี้เป็นส่วนขยายของการแก้ปัญหาการเวียนเกิดของฉันไปที่สามัญคำถาม Levenshtein ระยะทาง

คำอธิบาย:

ในการคำนวณการดัดแปลงขั้นต่ำที่จะได้รับจาก"xyz"ไป"yw"เรามุ่งเน้นไปที่อักขระตัวแรกของทั้งสองสตริง มีความเป็นไปได้สามประการ:

  • ลบ: Drop xจากสายแรกและซ้ำคำนวณการปรับเปลี่ยนจะได้รับจากการ"yz" นี้ผลตอบแทนถัวเฉลี่ยสามบรรทัด"yw" ["yz","yw"," M"]เพิ่มxไปที่อันแรกเว้นวรรคที่หนึ่งและRที่สาม เราได้รับ
    xyz
    YW
    RM
  • Add: Drop yจากสายที่สองและการคำนวณซึ่งจะส่งกลับผล"xyz" & "w" ["xyz","w","MRR"]เราจำเป็นต้องเพิ่มช่องว่างในบรรทัดแรกyไปยังบรรทัดที่สองและAบรรทัดที่สาม:
     xyz
    YW
    AMRR
  • ดัดแปลง / ไม่เปลี่ยนแปลง:"yz" & "w"เราสามารถรวมทั้งสองกรณีเพราะทั้งสองต้องวางอักษรตัวแรกของทั้งสตริงและคำนวณการปรับเปลี่ยนน้อยที่สุดระหว่างสายที่เหลือ: สำหรับผลลัพธ์["yz","w","MR"]เราเพิ่มที่บรรทัดxแรกและyบรรทัดที่สอง เฉพาะบรรทัดสุดท้ายที่เราต้องแยกความแตกต่างว่าตัวอักษรเริ่มต้นเหมือนกัน หากเป็นเหมือนกันช่องว่างจะถูกเพิ่มในบรรทัดที่สามมิฉะนั้น (เช่นในกรณีนี้เพราะx \= y) an Mถูกเพิ่ม:
    xyz
    YW
    MMR

จากผู้สมัครทั้งสามนั้นเราจำเป็นต้องค้นหาผู้ที่มีการปรับเปลี่ยนน้อยที่สุด สิ่งนี้เทียบเท่ากับการมีช่องว่างมากที่สุดในบรรทัดที่สาม ดังนั้นเราจึงแปลงผู้สมัครแต่ละคนs(รายการของสามสายอักขระ) เป็น tuple ([1|' '<-s!!2],s)ซึ่งsจะปรากฏเป็นองค์ประกอบที่สองและองค์ประกอบแรกคือรายการที่มีองค์ประกอบมากเท่าที่มีช่องว่างในบรรทัดที่สามของs( s!!2เนื่องจากการจัดทำดัชนี 0) เนื่องจากอิลิเมนต์รายการ1ถูกใช้ แต่องค์ประกอบจริงนั้นไม่เกี่ยวข้องตราบใดที่มันยังคงเหมือนเดิมสำหรับผู้สมัครทุกคน

ทั้งหมดนี้ให้รายการของสิ่งอันดับ

[([1], ["xyz", "yw", "RM"]), ([], ["xyz", "yw", "AMRR"]), ([], ["xyz", " YW", "MMR"])]
build-in maximumเลือกองค์ประกอบที่ใหญ่ที่สุดของรายการนี้โดยที่ tuples ถูกเปรียบเทียบโดยใช้คำศัพท์เฉพาะทางที่ประกอบไปด้วยส่วนประกอบจากซ้ายไปขวา เนื่องจาก[1]มีขนาดใหญ่กว่า[]tuple ตัวแรกจะถูกเลือกและsndส่งคืนคอมโพเนนต์ที่สองนั่นคือรายการของบรรทัดของ tuple


1 15 ไบต์เพื่อแก้ไขข้อผิดพลาดที่ - การAเปลี่ยนแปลงที่ส่วนท้ายของสตริงจะแสดงเป็นR-changes


lol นี้ทำให้ userscript คิดว่านี่เป็น 1 ไบต์
HyperNeutrino

8

JavaScript (ES6), 413 ... 343 342 ไบต์

บันทึก 5 ไบต์โดยปรับแต่งดัชนีลูปตามที่ @KevinCruijssen แนะนำ

รับอินพุตเป็น 2 สตริงในรูปแบบ currying ส่งคืนอาร์เรย์ 3 สตริง

b=>a=>{m=[];x=a.length;y=b.length;for(i=j=0,c=d='';i<=y;c+=R='R')m[i]=[[c,i++]];for(;j++<x;)m[i=0][j]=[d+=A='A',j];for(;i<y;i++)for(j=0;j<x;)[C]=m[[X,S]=m[i][j],[Y,I]=m[i+1][j],[Z,D]=m[i][++j],Q=[Z+R,D+1],i+1][j]=b[i]==a[j-1]?[X+' ',S]:S<I?D<S?Q:[X+'M',S+1]:D<I?Q:[Y+A,I+1];return[(g=s=>C.replace(/./g,c=>c==s?' ':b[i++],i=0))(A),g(R,b=a),C]}

กรณีทดสอบ

น้อย golfed

b => a => {
  m = []; x = a.length; y = b.length;

  // initialize the leftmost column and the topmost row
  for(i = j = 0, c = d = ''; i <= y; c += R = 'R')
    m[i] = [[c, i++]];
  for(; j++ < x;)
    m[i = 0][j] = [d += A = 'A', j];

  // walk through the Levenshtein matrix
  for(; i < y; i++)
    for(j = 0; j < x;)
      [C] = m[                                // C = current string, once updated
        [X, S] = m[i][j],                     // substitution
        [Y, I] = m[i + 1][j],                 // insertion
        [Z, D] = m[i][++j],                   // deletion
        Q = [Z + R, D + 1],                   // precomputed update for deletion
        i + 1
      ][j] =
        b[i] == a[j - 1] ?
          [X + ' ', S]                        // unchanged character
        :
          S < I ?
            D < S ? Q : [X + 'M', S + 1]      // deletion or substitution
          :
            D < I ? Q : [Y + A, I + 1];       // deletion or insertion

  return [
    // g = helper function to format the output strings by inserting spaces
    (g = s => C.replace(/./g, c => c == s ? ' ' : b[i++], i = 0))(A),
    g(R, b = a),

    // final modification string, picked from the last visited cell
    C
  ]
}

ตัวอย่าง

ด้านล่างเป็นเมทริกซ์เริ่มต้นสำหรับb = "foo"และa = "ok" :

//                     'o'           'k'
[ [ [ '',    0 ], [ 'A',   1 ], [ 'AA',  2 ] ],
  [ [ 'R',   1 ],  (undefined),  (undefined) ],  // 'f'
  [ [ 'RR',  2 ],  (undefined),  (undefined) ],  // 'o'
  [ [ 'RRR', 3 ],  (undefined),  (undefined) ] ] // 'o'

และนี่คือเมทริกซ์สุดท้ายหลังจากการทำซ้ำทั้งหมด:

//                     'o'           'k'
[ [ [ '',    0 ], [ 'A',   1 ], [ 'AA',  2 ] ],
  [ [ 'R',   1 ], [ 'M',   1 ], [ 'MA',  2 ] ],  // 'f'
  [ [ 'RR',  2 ], [ 'R ',  1 ], [ 'R A', 2 ] ],  // 'o'
  [ [ 'RRR', 3 ], [ 'RR ', 2 ], [ 'R M', 2 ] ] ] // 'o'

สตริงการดัดแปลงสุดท้ายพร้อมกับระยะทางของ Levenshtein จะถูกเก็บไว้ในเซลล์ล่างขวา


เปลี่ยนแปลงเดียวกันผมแนะนำเพื่อประหยัด 1 ไบต์เกี่ยวกับ -1 / + 1 jและxยังคงใช้กับการแก้ไขล่าสุดของคุณ: b=>a=>{m=[];x=a.length;y=b.length+1;for(i=y;i--;)m[i]=[[i,'R'.repeat(i)]];for(j=x+1;j--;)m[i=0][j]=[j,'A'.repeat(j)];for(;++i<y;)for(j=-1;++j<x;)R=m[S=(X=m[i-1][j])[0],I=(Y=m[i][j])[0],D=(Z=m[i-1][j+1])[0],Q=[D+1,Z[1]+'R'],i][j+1]=b[i-1]==a[j]?[S,X[1]+' ']:S<I?D<S?Q:[S+1,X[1]+'M']:D<I?Q:[I+1,Y[1]+'A'];return[(g=s=>R[1].replace(/./g,c=>c==s?' ':b[i++],i=0))('A'),g('R',b=a),R[1]]}:)
เควิน Cruijssen

1
@KevinCruijssen ฉันบันทึกได้ 5 ไบต์โดยนำความคิดของคุณไปอีกขั้น ขอบคุณ!
Arnauld

4

Python 2 , 548 536 484 500 1 488 447 381 2 373 371 357 350 ไบต์

s,t=input()
n,m=len(s),len(t)
r=range
L=[[(j,'RA'[i<1]*j)for j in r(i,m-~i)]for i in r(n+1)]
for i in r(n):
 for j in r(m):M,R=L[i][j:j+2];A=L[i+1][j];v,V=min(A,R,M);x=('AR'[v in R],'M_'[s[i]==t[j]])[v in M];_=M;X=eval(x)[1]+x;L[i+1][j+1]=v+(x<'_'),X
for i in r(len(X)):s=s[:i]+' '*('B'>X[i])+s[i:];t=t[:i]+' '*('R'==X[i])+t[i:]
print s+'\n'+t+'\n'+X

ลองออนไลน์!

ใช้'ARM_'แทน'ARM '

ทำงานโดยการสร้างเมทริกซ์ Levenshtein, และจากนั้นภายในข้างหลังเพื่อหาการดำเนินงาน ตอนนี้สร้างสตริงการดำเนินการในเวลาเดียวกันกับเมทริกซ์ Levenshtein เช่นเดียวกับคำตอบ JS ของ Arnauld

1: ไบต์เพิ่มเติมเนื่องจากมันไม่ทำงานหากสตริงแรกเป็นอักขระตัวเดียว

2: เปลี่ยนเป็นการสร้างชุดค่าผสมในเมทริกซ์ Levenshtein


+1 สำหรับการใช้เวลาน้อยกว่า 60 วินาทีสำหรับคำ 6 ตัวอักษรเช่นความพยายามครั้งแรก (ล้มเหลว) ของฉัน lol
HyperNeutrino

คำตอบที่ดี! +1 จากฉัน ตั้งแต่ฉันไม่เคยโปรแกรมในหลามฉันไม่สามารถจริงๆช่วยให้คุณกับการเล่นกอล์ฟยกเว้นสิ่งหนึ่งที่: สามารถm+i+1 m-~i
Kevin Cruijssen

คุณสามารถใช้แท็บแทนการเว้นวรรคสองบรรทัดในบรรทัดที่ 7
Stephen

คุณสามารถไปที่463 bytesโดยลด wile loop ให้เป็นหนึ่งบรรทัด:while i+j<n+m:v,A=(L[i]+[m,m])[j:j+2];R,M=(L[i+1]+[m,m])[j:j+2];d=min(A,R,M);q=M==d or(R==d)*2;r+=' '*(d==v==M)or'AMR'[q];i+=q>0;j+=q<2
ovs

1

Python 2 , 310 ไบต์

from difflib import*
a,b=input()
U,j=[],' '
for g,s,t,x,y in SequenceMatcher(0,a,b).get_opcodes():
	g,Y,T=g[0],y-x,t-s
	z,A,B=Y-T,a[s:t],b[x:y]
	if'q'<g:U+=[A+z*j,B+j*-z,'M'*min(T,Y)+'A'*z+'R'*-z]
	if'e'==g:U+=[A,B,j*Y]
	if'i'==g:U+=[j*Y,B,'A'*Y]
	if'e'>g:U+=[A,j*T,'R'*T]
for e in[0,1,2]:print''.join(U[e::3])

ลองออนไลน์!

การใช้difflib.SequenceMatcherที่คำนวณการจัดตำแหน่งระหว่างสองสาย


สิ่งนี้ดูเหมือนจะให้ผลลัพธ์ที่ไม่ถูกต้องสำหรับบางกรณีทดสอบอื่น ๆ ข้อมูลเพิ่มเติม:"This_is_an_example_text","This_is_a_test_as_example"
Kevin Cruijssen

@KevinCruijssen thanx ฉันเพิ่งแก้ไขมัน ^ _ ^
mdahmoune

ดีมาก gj! แต่อืมมม .. กรณีทดสอบครั้งที่สาม (และครั้งที่สี่เช่นกัน)ก็ไม่ถูกต้องเช่นกัน หนึ่งในสองบรรทัดควรถูกแก้ไข (ยกเว้นช่องว่างนำหน้า / ต่อท้าย) ปัจจุบันทั้งสองบรรทัดมีช่องว่างตรงกลาง
Kevin Cruijssen

@KevinCruijssen ขอบคุณอีกครั้งฉันกำลังแก้ไข
mdahmoune

1

Mathematica, 250 256 259 384 ไบต์

~ 0.00035 วินาทีสำหรับกรณีรหัส Java

(i=o=p="";a=Array;r=StringLength;If[Length@#>0,g=#&@@#;h=#[[2]];u=r@g;v=r@h;i=i<>g;o=o<>h;w=Abs[v-u];k=a[" "&,w];If[u<v,i=i<>k,o=o<>k];p=p<>a["M"&,u~Min~v];p=p<>a[If[u>v,"R","A"]&,w],i=i<>#;o=o<>#;p=p<>a[" "&,r@#]]&/@SequenceAlignment[#,#2];{i,o,p})&

การใช้งาน: f["ABCDE", "ABCDF"]

ลองออนไลน์!

รหัสจะขึ้นอยู่กับข้อเท็จจริงที่ใช้SequenceAlignmentงานได้ตามค่าเริ่มต้น

ด้วยการตั้งค่าเริ่มต้น SimilarityRules-> Automatic แต่ละการจับคู่ระหว่างองค์ประกอบสองส่วนจะมีค่า 1 ถึงคะแนนความคล้ายคลึงกันโดยรวมในขณะที่แต่ละค่าไม่ตรงกันการแทรกหรือการลบจะมีค่า -1

คือการให้คะแนนจะถูกคำนวณโดยM, AและRตาม

ตัวอย่าง:

ตัวอย่าง


2
อืมผมไม่เคยโปรแกรมใน Mathemetica แต่มันไม่ได้เป็นไปได้ที่จะเปลี่ยนi="";o="";p="";ไปi="";o=i;p=i;เพื่อลด 2 ไบต์?
Kevin Cruijssen

2
เกี่ยวกับi=o=p=""อะไร
DavidC

@DavidC ใช่ฉันรู้แล้วและเปลี่ยนมันแล้ว ขอบคุณอยู่ดี
Keyu Gan

1

D , 351 345 ไบต์

-6 ไบต์ thanx ถึง KevinCruijssen

string f(string a,string b){import std.algorithm;string x,y,z;size_t i,j,k;foreach(c;levenshteinDistanceAndPath(a,b)[1]){final switch(c)with(EditOp){case none:x~=a[i++];y~=b[j++];z~=" ";break;case substitute:x~=a[i++];y~=b[j++];z~="M";break;case insert:x~=" ";y~=b[j++];z~="A";break;case remove:x~=a[i++];y~=" ";z~="R";}}return x~"\n"~y~"\n"~z;}

ลองออนไลน์!


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