Dizeleri Bağlamla Birleştirin


13

Bağlamlı Dizeler

Bu zorluğun amaçları doğrultusunda, bağlamı olan bir dize, sol bağlam , veri bölümü ve sağ bağlam olarak adlandırılan üç dizeden oluşur . Daha uzun bir dizenin bir alt dizesini temsil eder. Dikey boruyu |ayırıcı olarak kullanıyoruz, bu nedenle bağlamlı bir dize örneği cod|e-go|lf, sol bağlamın, codverinin e-gove sağ bağlamın olduğu yerdir lf. Bu örnek, alt dize temsil e-goarasında code-golf.

Şimdi, iki dizeyi bağlamla birleştirmek için aa|bcc|deeve cc|de|eeeörneklerini kullanarak aşağıdaki gibi ilerliyoruz . Dizeleri diyagramdaki gibi hizalarız

a a|b c c|d e e
      c c|d e|e e e

böylece veri bölümleri bitişik olur. Birleştirmenin veri kısmı, bu durumda veri parçalarının birleştirilmesidir bccde. Sol bağlam, tüyleri bu durumda ilk veri bölümünün soluna kadar uzatan bölümdür aa. Benzer şekilde, doğru bağlam eee, yani birleştirme bağlamlı dizedir aa|bccde|eee. İkinci Örneğin, düşünün a|bb|cdve aabb|cd|ikinci kelime bir boş doğru bağlamı sahip olduğu,. Hizalama diyagramı

  a|b b|c d
a a b b|c d|

burada ikinci kelimenin sol bağlamı, ilk sözcüğün sol bağlamından daha fazla uzanır. Birleştirme aa|bbcd|.

Ama bekleyin, bir sorun var: hizalama diyagramının harfleri eşleşmezse, birleştirme mevcut değildir! Bir örnek olarak, bir diyagram olarak aa|bb|ccve c|c|cIS

a a|b b|c c
      c|c|c

burada bve cdördüncü sütundaki katılmadıkları için birleştirilemezler.

Görev

İşiniz, bölümleri |yukarıdaki gibi ayrılmış olan iki dizeyi alan ve varsa birleştirmelerini ve yoksa başka bir şeyi çıkaran bir program yazmaktır . "Başka bir şey", bağlamı olan geçerli bir dize olmadığı ve her durumda aynı olduğu sürece, çıktısız dahil herhangi bir değer olabilir. Ancak, hata atmak kabul edilemez. Bir STDIN-STDOUT programı veya bir işlev verebilirsiniz ve anonim işlevler de kabul edilir. En küçük bayt sayısı kazanır ve standart boşluklara izin verilmez.

Test Durumları

aa|bcc|dee cc|de|eee -> aa|bccde|eee
a|bb|cd    aabb|cd|  -> aa|bbcd|
a|b|cccd   aab|cc|c  -> aa|bcc|cd
a|b|c      b||cd     -> a|b|cd
aa|bb|cc   c|c|c     -> None
aaa|b|c    abb|cd|d  -> None
|bb|cd     abb|c|ed  -> None
a|b|c      a||cd     -> None

Yanıtlar:


4

Haskell, 184 182 201 199 155

s&t|(a,'|':b)<-f t,(x,'|':y)<-f$r s,x#b,a#y=r(y!r a)++b!r x|0<1=""
r=reverse
a!b=a++drop(length a-1)b
(#)a=and.zipWith(==)(r a).filter h
f=span h
h=(/='|')

örnek çalıştırma:

"|a|"&"|b|" -- returns "|ab|"
"|a|x"&"|b|" -- returns ""

eşleşme yoksa boş bir dize döndürülür. aksi halde sonuç iade edilir.

kısmi açıklama:

# iki dize alan ve eşleşip eşleşmediklerini döndüren bir işlevdir.

! iki dizge alır ve ilki, ikincisinden fazladan karakterle birleştirilmiş (varsa) döndürür.

ana işlevi &kullanır span (/='|'), iki bölüme girdi bölmek a|b|ciçin a, b|cbağlamları eşleşirse, çekler ve sonra kullandığı !çıktı monte iki kez.

Edit: mage-late regolfing oldukça etkili gibi görünüyor.


Hmm, bir hata atmanın, özellikle bir işlev için kabul edilebilir bir çıktı yöntemi olmadığından korkuyorum. |1<2=""Tanımına ekleyerek &bunu çözmelisiniz. Üzgünüm bunu daha açık bir şekilde belirtmedim, onu düzenleyeceğim.
Zgarb

@Zgarb Aslında, bu düzeltmezdi. '|'Dizeler eşleşmediğinde çok fazla işaret içeren bir dize döndürmek iyi mi?
proud haskeller

Elbette, eşleşmeyen tüm girişler için aynı dize olduğu sürece.
Zgarb

3

Python (242 bayt)

import itertools as i
s='|'
j=''.join
r=reversed
m=lambda a,b:j(j(*set(p+q))for p,q in i.izip_longest(a,b,fillvalue=''))
def c(A,B):
 u,v,w,x,y,z=(A+s+B).split(s)
 try:return j(r(m(r(u+v),r(x))))[:-len(v)]+s+v+y+s+m(w,y+z)[len(y):]
 except:0

açıklama

Lambda işlevi m, ortak bir önek paylaştıkları sürece iki dizeden daha uzun döndürür. Boş dizesinin yapar ''sonra sonucun dönüm, eksik değerler yerine (formlar alabilir aa, ab, aveya bmaç / uyumsuzluk / eşitsiz uzunlukları durumlarında) her pozisyonda benzersiz bir karakter kümesi haline. jointek bir argüman beklediğinden, birden fazla öğeyle bir kümenin paketinin açılması, kümenin yükselmesine neden olur TypeError.

Ana işlev daha sonra

  • kullanımları mbirleştirmek sol bağlam ve veri parçasını ilk kelimesi sol çerçevede (sol üzerinde ters dizelere sağdan) ikinci
  • veri bölümlerini birleştirir,
  • ve yine ilk kelimenin doğru bağlamını ikinci bölümün veri kısmı ve doğru bağlamı ile mbirleştirmek için kullanır

İki orijinal sözcüğün veri parçaları, yeni bağlamların sağ ve sol tarafından kesilir.

Yanlış hizalamaların bir artışa neden olduğunu bildiğimiz miçin TypeError, bu durumlarda istisnayı yakalar ve dolaylı olarak geri döneriz None.

Test yapmak

TESTCASES = [
    ('aa|bcc|dee', 'cc|de|eee', 'aa|bccde|eee'),
    ('a|bb|cd', 'aabb|cd|', 'aa|bbcd|'),
    ('a|b|cccd', 'aab|cc|c', 'aa|bcc|cd'),
    ('a|b|c', 'b||cd', 'a|b|cd'),
    ('aa|bb|cc', 'c|c|c', None),
    ('aaa|b|c', 'abb|cd|d', None),
    ('|bb|cd', 'abb|c|ed', None),
    ('a|b|c', 'a||cd', None),
]

for A, B, R in TESTCASES:
    print '{:<10} {:<9} -> {}'.format(A, B, c(A, B))

Çıktı

aa|bcc|dee cc|de|eee -> aa|bccde|eee
a|bb|cd    aabb|cd|  -> aa|bbcd|  
a|b|cccd   aab|cc|c  -> aa|bcc|cd 
a|b|c      b||cd     -> a|b|cd    
aa|bb|cc   c|c|c     -> None      
aaa|b|c    abb|cd|d  -> None      
|bb|cd     abb|c|ed  -> None      
a|b|c      a||cd     -> None  
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.