Concatenar seqüências de caracteres com contexto

13

Strings com contexto

Para os propósitos desse desafio, uma string com contexto é um triplo de strings, chamado contexto esquerdo , parte de dados e contexto correto . Representa uma substring de uma string mais longa. Usamos o tubo vertical |como um separador; portanto, um exemplo de uma string com contexto é cod|e-go|lf: onde está o contexto esquerdo cod, os dados e-goe o contexto correto lf. Este exemplo representa a substring e-gode code-golf.

Agora, para concatenar duas seqüências de caracteres com o contexto, procedemos da seguinte maneira, usando aa|bcc|deee cc|de|eeecomo exemplos. Alinhamos as strings como no diagrama

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

para que suas partes de dados sejam adjacentes. A parte de dados da concatenação é a concatenação das partes de dados, neste caso bccde. O contexto esquerdo é a parte que se estende mais à esquerda da primeira parte de dados, neste caso aa. Da mesma forma, o contexto correto é eee, portanto, a concatenação é a sequência com o contexto aa|bccde|eee. Para um segundo exemplo, considere a|bb|cde aabb|cd|, onde a segunda palavra tem um contexto correto vazio. O diagrama de alinhamento é

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

onde o contexto esquerdo da segunda palavra se estende além do da primeira. A concatenação é aa|bbcd|.

Mas espere, há uma dica: se as letras do diagrama de alinhamento não coincidirem, a concatenação não existe! Como exemplo, o diagrama de aa|bb|cce c|c|cé

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

onde be cna quarta coluna discordam, portanto não podem ser concatenadas.

A tarefa

Seu trabalho é escrever um programa que use duas seqüências de caracteres com contexto cujas partes são separadas por |acima, e que produza sua concatenação, se houver, e outra coisa, se não. O "algo mais" pode ter qualquer valor, incluindo nenhuma saída, desde que não seja uma sequência válida com contexto e seja a mesma em todos os casos. No entanto, lançar um erro não é aceitável. Você pode fornecer um programa STDIN para STDOUT ou uma função, e funções anônimas também são aceitas. A menor contagem de bytes vence e as brechas padrão não são permitidas.

Casos de teste

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
fonte

Respostas:

4

Haskell, 184 182 201 199 155 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=(/='|')

exemplo execute:

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

se não houver uma correspondência, uma string vazia será retornada. caso contrário, o resultado seria retornado.

explicação parcial:

# é uma função que obtém duas strings e retorna se elas correspondem ou não.

! obtém duas strings e retorna a primeira concatenada com caracteres extras a partir da segunda (se houver alguma).

a função principal &usa span (/='|')para dividir as entradas em duas partes, a|b|cpara a, b|c, verifica se os contextos correspondem e depois usa !duas vezes para montar a saída.

Edit: regolfing mago-tarde parece ser bastante eficaz.

orgulhoso haskeller
fonte
Hummm, receio que lançar um erro não seja um método de saída aceitável, especialmente para uma função. Adicionando |1<2=""à definição de &deve resolver isso. Me desculpe, eu não especificou isso mais explicitamente nas especificações, eu vou editá-lo no.
Zgarb
@ Zgarb Na verdade, isso não corrigi-lo. Retornar uma string com muitos '|'sinais quando as strings não coincidem?
proud haskeller
Claro, desde que seja a mesma sequência para todas as entradas não correspondentes.
Zgarb
3

Python (242 bytes)

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

Explicação

A função lambda mretorna a mais longa das duas seqüências, desde que elas compartilhem um prefixo comum. Ele faz isso através da concatenação a cadeia vazia ''em vez de todos os valores em falta, em seguida, transformando o resultado (o qual pode tomar a forma aa, ab, a, ou bem casos de fósforo / desadaptação / comprimentos desiguais) para um conjunto de caracteres originais em cada posição. joinespera um único argumento, portanto, descompactar um conjunto com mais de um elemento fará com que ele aumente a TypeError.

A função principal então

  • usa mpara combinar o contexto esquerdo e os dados dividem a primeira palavra com o contexto esquerdo da segunda (da direita para a esquerda, sobre cadeias invertidas)
  • concatena partes de dados,
  • e novamente usa mpara combinar o contexto correto da primeira palavra com a parte dos dados e o contexto correto da segunda

As partes de dados das duas palavras originais são cortadas dos lados direito e esquerdo dos novos contextos.

Como sabemos que os desalinhamentos causam maumento de a TypeError, nesses casos capturamos a exceção e retornamos implicitamente None.

Teste

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

Resultado

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
fonte