String Gabungan dengan Konteks

13

String dengan Konteks

Untuk keperluan tantangan ini, string dengan konteks adalah tiga string, yang disebut konteks kiri , bagian data , dan konteks yang benar . Ini mewakili substring dari string yang lebih panjang. Kami menggunakan pipa vertikal |sebagai pemisah, jadi contoh string dengan konteks adalah cod|e-go|lf, di mana konteks kiri cod, data e-go, dan konteks yang benar lf. Contoh ini mewakili substring e-godari code-golf.

Sekarang, untuk menyatukan dua string dengan konteks, kami melanjutkan sebagai berikut, menggunakan aa|bcc|deedan cc|de|eeesebagai contoh. Kami menyelaraskan string seperti pada diagram

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

sehingga bagian data mereka berdekatan. Bagian data dari rangkaian adalah gabungan bagian data, dalam hal ini bccde. Konteks kiri adalah bagian yang memanjang lebih jauh ke kiri dari bagian data pertama, dalam hal ini aa. Demikian pula, konteks yang tepat adalah eee, jadi rangkaiannya adalah string dengan konteks aa|bccde|eee. Untuk contoh kedua, pertimbangkan a|bb|cddan aabb|cd|, di mana kata kedua memiliki konteks kanan kosong. Diagram penyelarasan adalah

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

di mana konteks kiri kata kedua meluas lebih jauh dari yang pertama. Rangkaiannya adalah aa|bbcd|.

Tapi tunggu, ada gotcha: jika huruf-huruf diagram alinyemen tidak cocok, maka tidak ada concatenation! Sebagai contoh, diagram aa|bb|ccdan c|c|cis

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

di mana bdan cpada kolom keempat tidak setuju, sehingga mereka tidak bisa digabungkan.

Tugas

Tugas Anda adalah menulis sebuah program yang terdiri dari dua string dengan konteks yang bagian-bagiannya dipisahkan |seperti di atas, dan menampilkan rangkaiannya jika ada, dan sesuatu yang lain jika tidak. "Sesuatu yang lain" bisa berupa nilai apa saja, termasuk tidak ada keluaran, asalkan itu bukan string yang valid dengan konteks, dan itu sama dalam semua kasus. Namun, melempar kesalahan tidak dapat diterima. Anda dapat memberikan program STDIN-ke-STDOUT atau fungsi, dan fungsi anonim juga diterima. Hitungan byte terkecil menang, dan celah standar tidak diizinkan.

Uji Kasus

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

Jawaban:

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=(/='|')

contoh dijalankan:

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

jika tidak ada kecocokan, string kosong akan dikembalikan. jika tidak hasilnya akan dikembalikan.

penjelasan parsial:

# adalah fungsi yang mendapat dua string, dan mengembalikan apakah cocok atau tidak.

! mendapat dua string dan mengembalikan yang pertama disatukan dengan karakter tambahan dari yang kedua (jika ada).

fungsi utama &digunakan span (/='|')untuk membagi input menjadi dua bagian, a|b|cuntuk a, b|c, memeriksa apakah konteksnya cocok, dan kemudian menggunakan !dua kali untuk merakit output.

Sunting: penyihir terlambat terlambat tampaknya cukup efektif.

haskeller bangga
sumber
Hmm, saya khawatir bahwa melempar kesalahan bukanlah metode keluaran yang dapat diterima, terutama untuk suatu fungsi. Menambahkan |1<2=""ke definisi &harus menyelesaikannya. Maaf saya tidak menyebutkan ini secara lebih spesifik dalam spesifikasi, saya akan mengeditnya.
Zgarb
@ Zgarb Sebenarnya, ini tidak akan memperbaikinya. Apakah mengembalikan string dengan terlalu banyak '|'tanda saat senar tidak cocok?
haskeller bangga
Tentu, selama itu adalah string yang sama untuk semua input yang tidak cocok.
Zgarb
3

Python (242 byte)

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

Penjelasan

Fungsi lambda mmengembalikan lebih lama dari dua string selama mereka berbagi awalan yang sama. Hal ini dilakukan dengan concatenating string kosong ''di tempat nilai-nilai yang hilang, maka mengubah hasil (yang mungkin mengambil bentuk aa, ab, a, atau bdalam kasus-kasus pertandingan / ketidakcocokan / panjang yang tidak sama) menjadi satu set karakter unik pada setiap posisi. joinmengharapkan satu argumen, jadi membongkar set dengan lebih dari satu elemen akan menyebabkannya memunculkan a TypeError.

Fungsi utamanya kemudian

  • menggunakan muntuk menggabungkan konteks kiri dan data bagian kata pertama dengan konteks kiri yang kedua (dari kanan ke kiri string terbalik)
  • menggabungkan bagian data,
  • dan sekali lagi digunakan muntuk menggabungkan konteks yang benar dari kata pertama dengan bagian data dan konteks yang benar dari kata kedua

Bagian data dua kata asli 'dipangkas dari sisi kanan dan kiri konteks baru.

Karena kita tahu bahwa ketidaksejajaran menyebabkan mpeningkatan TypeError, dalam kasus ini kita menangkap pengecualian dan secara implisit kembali None.

Pengujian

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

Keluaran

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