Об'єднайте рядки з контекстом


13

Струни з контекстом

Для цілей цього виклику рядок з контекстом - це потрійний рядок, який називається лівим контекстом , частиною даних та правим контекстом . Він являє собою підрядку з більш тривалого рядка. Ми використовуємо вертикальну трубу |як роздільник, тому приклад рядка з контекстом є cod|e-go|lf, де лівий контекст cod, дані є e-go, а правий - контекст lf. Цей приклад є підрядок e-goз code-golf.

Тепер, щоб з'єднати два рядки з контекстом, ми походимо наступним чином, використовуючи aa|bcc|deeі cc|de|eeeяк приклади. Вирівнюємо рядки, як на схемі

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

щоб їх частини даних були суміжними. Частина даних конкатенації - це конкатенація частин даних, в цьому випадку bccde. Лівий контекст - це частина, яка поширюється вліво від першої частини даних, в даному випадку aa. Аналогічно правильний контекст є eee, тому конкатенація - це рядок з контекстом aa|bccde|eee. Для другого прикладу розглянемо a|bb|cdта aabb|cd|, де друге слово має порожній правильний контекст. Діаграма вирівнювання є

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

де лівий контекст другого слова поширюється далі, ніж перший. Конкатенація є aa|bbcd|.

Але зачекайте, є ось що: якщо літери діаграми вирівнювання не збігаються, конкатенація не існує! Як приклад, діаграма aa|bb|ccі c|c|cє

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

де bі cна четвертому стовпці не погоджуються, тому їх не можна об'єднати.

Завдання

Ваше завдання - написати програму, яка складається з двох рядків з контекстом, частини яких розділені |як вище, і виводить їх конкатенацію, якщо вона існує, і щось інше, якщо ні. "Щось інше" може мати будь-яке значення, включаючи відсутність виводу, доки це не дійсна рядок з контекстом, і воно однакове у всіх випадках. Однак помилка кидання не прийнятна. Ви можете надати або програму STDIN-STDOUT, або функцію, а також приймаються анонімні функції. Найменший байт виграє, а стандартні лазівки заборонені.

Випробування

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

Відповіді:


4

Хаскелл, 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=(/='|')

Приклад запуску:

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

якщо немає відповідності, повернеться порожній рядок. інакше результат буде повернутий.

часткове пояснення:

# це функція, яка отримує два рядки і повертає, чи відповідають вони чи ні.

! отримує два рядки і повертає перше, з'єднане з додатковим символом з другого (якщо такі є).

основна функція &використовує span (/='|')для розділення входів на дві частини, a|b|cщоб a, b|cперевірити, чи контекст відповідає, а потім !двічі використовує для збирання виводу.

Редагувати: маго-пізнє переоформлення здається досить ефективним.


Хм, боюся, що помилка кидання не є прийнятним методом виводу, особливо для функції. Додавання |1<2=""до визначення &слід вирішити це. Вибачте, що я не вказав це більш чітко в специфікаціях, я відредагую його.
Zgarb

@Zgarb Насправді це не виправить. Чи повертається рядок із занадто великою кількістю '|'знаків, коли рядки не відповідають нормам?
гордий haskeller

Звичайно, якщо це однаковий рядок для всіх невідповідних входів.
Згарб

3

Python (242 байти)

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

Пояснення

Функція лямбда mповертає більше двох рядків, доки вони мають спільний префікс. Вона робить це шляхом конкатенації порожнього рядка ''замість яких - або відсутніх значень, то повертаючи результат (який може приймати форми aa, ab, aабо bу випадках матчу / неузгодженість / різна довжина) в набір унікальних символів в кожній позиції. joinочікує єдиного аргументу, тому розпакування набору з більш ніж одним елементом призведе до того, що він збільшить a TypeError.

Основна функція тоді

  • використовує mдля поєднання лівого контексту та частини даних перше слово з лівим контекстом другого (справа наліво над перевернутими рядками)
  • об'єднує частини даних,
  • і знову використовує mдля поєднання правильного контексту першого слова з частиною даних та правильним контекстом другого

Частини даних двох оригінальних слів оброблені з правої та лівої сторін нового контексту.

Оскільки ми знаємо, що несогласованность викликає mпідвищення a TypeError, в цих випадках ми виловлюємо виняток і неявно повертаємося None.

Тестування

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

Вихідні дані

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  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.