Değişimi sevmiyorum!


19

Giriş:

Satırları veya boşlukları olmayan iki dize.

Çıktı:

Her iki giriş dizesi ayrı satırlarda, gerekirse iki dizgiden biri için boşluklarla . Ve karakterlerle üçüncü satır A, R, Mve , ifade eden ilave , çıkarılabilir , değiştirilebilir ve değişmez .

Üst veya alt giriş dizesine boşluk ekleriz (gerekirse). Bu zorluğun amacı ARM, Levenshtein mesafesi olarak da bilinen, mümkün olan en az miktarda değişiklikle ( ) çıkış yapmaktır .

Misal:

Diyelim ki girdi dizeleri ABCDEFve AFBECDsonra çıktı şu olacaktır:

A B CDEF
AFBECD  
 A A  RR

Örnek olarak bazı olası geçersiz çıktılar (ve çok daha fazlası var):

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

Ancak bunların hiçbirinde sadece dört değişiklik yok, sadece A B CDEF\nAFBECD \n A A RR bu zorluk için geçerli bir çıktı.

Zorluk kuralları:

  • Giriş dizelerinin yeni satır veya boşluk içermediğini varsayabilirsiniz.
  • İki giriş dizesi farklı uzunluklarda olabilir.
  • İki giriş dizesinden biri, isteğe bağlı ön / arka boşluklar dışında olduğu gibi kalmalıdır.
  • Dilleriniz ASCII dışında hiçbir şeyi desteklemiyorsa, girişin yalnızca yazdırılabilir ASCII karakterleri içereceğini varsayabilirsiniz.
  • Giriş ve çıkış formatları esnektir. Üç ayrı Dizeniz, bir String dizisi, yeni satırlı tek bir String, 2D karakter dizisi vb. Olabilir.
  • Bunun yerine başka bir şey kullanmanıza izin verilir ARM, ancak ne kullandığınızı belirtin (yani 123veyaabc. , vs.)
  • Aynı miktarda değişiklik ( ARM) ile birden fazla geçerli çıktı mümkünse , olası çıktılardan birini veya tümünü çıktılamayı seçebilirsiniz.
  • Önde gelen ve arkadaki boşluklar isteğe bağlıdır:

    A B CDEF
    AFBECD
     A A  RR
    

    veya

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

Genel kurallar:

  • Bu , bayt en kısa cevap kazanır.
    Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi engellemesine izin vermeyin. 'Herhangi bir' programlama dili için olabildiğince kısa bir cevap bulmaya çalışın.
  • Cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyon / yöntemi uygun parametrelerle, tam programları kullanmanıza izin verilir. Çağrınız.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için test içeren bir bağlantı ekleyin.
  • Ayrıca, gerekirse bir açıklama ekleyin.

Test senaryoları:

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 


Aynı mesafede olan birden fazla düzenleme varsa, bunlardan yalnızca birini çıktılamak uygun mudur?
AdmBorkBork

@AdmBorkBork Evet, olası çıktılardan sadece biri gerçekten amaçlanan çıktıdır (mevcut tüm seçeneklerin çıktısı da iyidir). Bunu meydan okuma kurallarında açıklığa kavuşturacağım.
Kevin Cruijssen

@ Önde gelen boşluklarla ilgili kuralı kaldırdım, bu nedenle önde gelen ve sondaki boşluklar değiştirilmemiş satırda hem isteğe bağlı hem de geçerlidir. (Bu, yanıtınızdaki son test durumunun tamamen geçerli olduğu anlamına gelir.)
Kevin Cruijssen

1
@Ferrybig Ah tamam, açıklama için teşekkürler. Ancak bu zorluğa gelince, sadece yazdırılabilir ASCII'yi desteklemek zaten yeterli. Daha fazlasını desteklemek istiyorsanız, misafirim olun. Ancak verilen test senaryoları için çalıştığı sürece, 1'den fazla karakterden oluşan grafen kümeleri için tanımlanmamış davranışla tamamım. :)
Kevin Cruijssen

Yanıtlar:


5

Haskell , 192 181 174 161 158 150 147 143 158 1 bayt

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

Çevrimiçi deneyin! Örnek kullanımı: "ABCDEF" & "AFBECD". Üç dizenin bir listesini döndürür. Bu, özyinelemeli çözümün sıradan Levenshtein mesafe sorununa bir uzantısıdır .

Açıklama:

Aldığım minimal değişiklikler hesaplamak için "xyz"için "yw", her iki dizeleri ilk karakter odaklanır. Üç olasılık vardır:

  • : Kaldır Bırak xilk dizesinden ve özyinelemeli almak değişiklikler hesaplamak "yz"için "yw". Bu üç çizgi verir ["yz","yw"," M"]. EklexBirincisine, ikincisine ve Rüçüncüsüne bir boşluk . Biz olsun
    xyz
    yw
    RM
  • Ekle: Sonucu döndüren yikinci dizeden ve hesaplamadan "xyz" & "w"çıkar ["xyz","w","MRR"]. İlk satıra bir boşluk eklememiz gerekiyor,y ikinci veA satıra ve üçüncü satıra :
     xyz
    yw
    AMRR
  • Modifiye / Değişmeyen: Her iki her iki dizeleri ilk karakteri bırakın ve kalan dizeleri arasındaki asgari değişiklikler hesaplamak için ihtiyaç çünkü bu iki durumu birleştirebilirsiniz: "yz" & "w". Sonuç olarak ["yz","w","MR"], xonu birinci ve yikinci hatta ekliyoruz . Sadece son satır için ilk karakterlerin aynı olup olmadığını ayırt etmeliyiz. Aynılarsa, üçüncü satıra bir boşluk eklenir, aksi takdirde (bu durumda olduğu gibi x \= y) bir Man eklenir:
    xyz
    yw
    MMR

Bu üç adaydan en az modifikasyona sahip olanı bulmamız gerekiyor. Bu, üçüncü satırda en fazla boşluğa sahip olmakla eşdeğerdir. Bu nedenle, her bir aday dönüştürmek sbir tuplea (üç dizgi listesi) ([1|' '<-s!!2],s), süçüncü satır boşluk vardır olarak birçok elemanlar olarak, ikinci bileşen, ilk bileşen olarak görünür bir listesi s( s!!2çünkü 0-indeksleme). Liste öğesi 1kullanıldığından, ancak gerçek öğe tüm adaylar için aynı olduğu sürece önemsizdir.

Tamamen, bu tuples listesini verir

[([1], ["xyz", "yw", "RM"]), ([], ["xyz", "yw", "AMRR"]), ([], ["xyz", " yw", "MMR"])]
Yap- maximumseçer soldan sağa Bileşen genelinde olduğu küpe leksikografik karşılaştırılır bu listede, en büyük elemanı. Bundan [1]daha büyük olduğu []gibi, ilk grup seçilir ve sndbileşenin ikincisini, yani grubun satır listesini döndürür.


ADizenin sonundaki R-changes öğesinin -changes olarak görüntüleneceği bir hatayı düzeltmek için 1 +15 bayt


lol bu usercript'in 1 bayt olduğunu düşünüyor
HyperNeutrino

8

JavaScript (ES6), 413 ... 343 342 bayt

@KevinCruijssen tarafından önerilen döngü indekslerini değiştirerek 5 bayt tasarruf etti

Körili sözdiziminde girdiyi 2 dize olarak alır. 3 dizeden oluşan bir dizi döndürür.

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

Test senaryoları

Daha az golf

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

Misal

Aşağıda b = "foo" ve a = "ok" için başlangıç ​​matrisi verilmiştir :

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

ve işte tüm iterasyonlardan sonraki son matris:

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

Son modifikasyon dizisi Levenshtein mesafesi ile birlikte sağ alt hücrede saklanır.


Aynı değişiklik -1 / + 1 ile ilgili olarak 1 bayt kaydetmeyi jxb=>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]]}
önerdim

1
@KevinCruijssen Fikrinizi bir adım daha ileri götürerek 5 bayt kazandım. Teşekkürler!
Arnauld

4

Python 2 , 548 536 484 500 1 488 447 381 2 373 371 357 350 bayt

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

Çevrimiçi deneyin!

Kullanımları 'ARM_' yerine'ARM '

Levenshtein matrisini oluşturarak ve sonra işlemleri bulmak için geriye doğru hareket ederek çalışır . Şimdi Operauld dizesini Levuldhtein matrisi ile aynı anda inşa ediyor, Arnauld'un JS cevabında olduğu gibi

1: Daha fazla bayt, çünkü ilk dize tek bir karakterse işe yaramadı.

2: Levenshtein matrisindeki kombinasyonların oluşturulmasına geçildi.


Başlangıç ​​(başarısız) girişimim lol gibi 6 karakter kelimesi için 60 saniyeden az
sürdüğü için +1

Güzel cevap! Benden +1. Python'da hiç programlamadığım için golf konusunda size gerçekten yardımcı olamıyorum, tek bir şey hariç: m+i+1olabilir m-~i.
Kevin Cruijssen

7. satırdaki çift boşluk yerine bir sekme kullanabilirsiniz.
Stephen

Wile döngüsünü bir satıra indirerek 463 bayta ulaşabilirsiniz :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 bayt

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

Çevrimiçi deneyin!

difflib.SequenceMatcherBunu kullanmak iki dize arasındaki hizalamayı hesaplar


Bu, diğer test vakalarının bazıları için bazı yanlış sonuçlar veriyor gibi görünüyor. Daha spesifik:"This_is_an_example_text","This_is_a_test_as_example"
Kevin Cruijssen

@KevinCruijssen thanx, ben sadece çözdüm ^ _ ^
mdahmoune

Güzel, gj! Ama umm .. üçüncü test durumu (ve dördüncü) maalesef yanlış. İki çizgiden biri değiştirilmemelidir (ön / arka boşluklar hariç). Her iki satır da şu anda ortada boşluklar içeriyor.
Kevin Cruijssen

@KevinCruijssen tekrar teşekkürler,
düzeltiyorum

1

Mathematica, 250 256 259 384 bayt

Java kodu durumu için ~ 0.00035 saniye.

(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})&

Kullanımı: f["ABCDE", "ABCDF"]

Çevrimiçi deneyin!

Kod, SequenceAlignmentvarsayılan olarak şu şekilde çalışan bir gerçeğe dayanır :

SimilarityRules-> Automatic varsayılan ayarıyla, iki öğe arasındaki her eşleşme toplam benzerlik puanına 1, her uyumsuzluk, ekleme veya silme -1'e katkıda bulunur.

Yani, skor hesaplanır M, Ave Rbuna bağlı olarak,.

Misal:

misal


2
Hmm, o değiştirmek mümkün değildir Mathemetica programlanmış, ancak hiç i="";o="";p="";üzere i="";o=i;p=i;2 bayt azaltmak için?
Kevin Cruijssen

2
Ne olmuş i=o=p=""?
DavidC

@DavidC Evet Bunu fark ettim ve zaten değiştirdim. Yine de teşekkür ederim
Keyu Gan

1

D , 351 345 bayt

Kevin Cruijssen'e -6 bayt thanx

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

Çevrimiçi deneyin!


Son baytını kaldırarak altı bayt golf oynayabilirsiniz break;. +1 olsa da, ilk kez programlama dilini görüyorum D.
Kevin Cruijssen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.