Una relación al revés

10

Escriba un programa o función que, dadas dos cadenas ASCII Ay B, producirá cadenas A'y B'donde las subcadenas comunes se invierten en su lugar. El proceso para encontrar A'es el siguiente:

  1. A' Inicialmente está vacío.
  2. Si el primer carácter de Aestá en B, encuentre el prefijo más largo del Acual es una subcadena de B. Elimine este prefijo de Ay agregue su inversión a A'.
  3. De lo contrario, elimine este primer carácter Ay agréguelo a A'.
  4. Repita los pasos 2-3 hasta que Aesté vacío.

El hallazgo B'se realiza de manera similar.

Ejemplo

Consideremos las cadenas A = "abc bab"y B = "abdabc". Pues A'esto es lo que sucede:

  • A = "abc bab": El primer carácter "a"está en B y el prefijo más largo de A encontrado en B es "abc". Eliminamos este prefijo de A y agregamos su inversión "cba"a A '.
  • A = " bab": El primer carácter " "no está en B, por lo que eliminamos este carácter de A y lo agregamos a A '.
  • A = "bab": El primer carácter "b"está en B y el prefijo más largo de A encontrado en B es "b". Eliminamos este prefijo de A y agregamos su inversión (que todavía está "b") a A '.
  • A = "ab": El primer carácter "a"está en B y el prefijo más largo de A encontrado en B es "ab". Eliminamos este prefijo de A y agregamos su inversión "ba"a A '.
  • A = "": A está vacío, así que nos detenemos.

Así llegamos A' = "cba" + " " + "b" + "ba" = "cba bba". Para B ', el proceso es similar:

B = "abdabc"  ->  "a" in A, remove prefix "ab"
B = "dabc"    ->  "d" not in A, remove "d"
B = "abc"     ->  "a" in A, remove prefix "abc"

Así llegamos B' = "ba" + "d" + "cba" = "badcba".

Finalmente, devolvemos las dos cadenas, es decir

(A', B') = ("cba bba", "badcba")

Casos de prueba

"abc bab", "abdabc" -> "cba bba", "badcba"
"abcde", "abcd bcde" -> "dcbae", "dcba edcb"
"hello test", "test banana" -> "hello tset", "tset banana"
"birds flying high", "whistling high nerds" -> "bisdr flyhgih gni", "wihstlhgih gni nesdr"

El código más corto en bytes gana.

orlp
fuente
¿Suponemos que todas las entradas son minúsculas ASCII? ¿Se espera que el resultado exacto sea similar a "cba bba", "badcba"incluir comillas y comas?
AdmBorkBork
@TimmyD El formato exacto de entrada / salida es su elección. No puede presumir que la entrada es ASCII en minúsculas, podría ser cualquier ASCII imprimible.
orlp
¿Es la cadena vacía una entrada legal?
MtnViewMark
@MtnViewMark Sí.
orlp

Respuestas:

1

Pyth, 29 bytes

M&G+_Je|f}TH._GhGg.-GJHgzQgQz

Arnés de prueba.

El formato de entrada es:

abc bab
"abdabc"

Salida es:

cba bba
badcba
isaacg
fuente
2

Haskell, 120 111 bytes

import Data.List
a&b=(a#b,b#a)
[]#_=[]
(a:y)#b=[a]%y where p%(i:w)|reverse(i:p)`isInfixOf`b=(i:p)%w;p%x=p++x#b

Pruebas de funcionamiento:

λ: "abc bab"&"abdabc"
("cba bba","badcba")

λ: "abcde"&"abcd bcde"
("dcbae","dcba edcb")

λ: "hello test"&"test banana"
("hello tset","tset banana")

λ: "birds flying high"&"whistling high nerds"
("bisdr flyhgih gni","wihstlhgih gni nesdr")
MtnViewMark
fuente
1

SWI-Prolog, 312 bytes

a(A,B,X,Y):-b(A,B,"",X),b(B,A,"",Y).
b(A,B,R,Z):-A="",R=Z;sub_string(A,0,1,_,C),(sub_string(B,_,1,_,C),(string_length(A,J),I is J-1,between(0,I,K),L is J-K,sub_string(A,0,L,_,S),sub_string(B,_,L,_,S),string_codes(S,E),reverse(E,F),string_codes(Y,F));S=C,Y=C),string_concat(S,V,A),string_concat(R,Y,X),b(V,B,X,Z).

Ejemplo: a("birds flying high","whistling high nerds",X,Y).salidas

X = "bisdr flyhgih gni",
Y = "wihstlhgih gni nesdr" .

Una manera, forma una solución demasiado tiempo que va demasiado mostrar el nivel de detalle Prolog es cuando se trata de cadenas. Podría ser posible acortar esto usando arrays de códigos ( `birds flying high`) en lugar de cadenas ( "birds flying high").

Fatalizar
fuente
1

Python 2.7, 169 156 152 141 bytes

m=lambda A,B:(b(A,B),b(B,A))
def b(A,B,C=''):
 while A:j=next((j for j in range(len(A),0,-1)if A[:j]in B),1);C+=A[:j][::-1];A=A[j:]
 return C

La función mtoma las 2 cadenas como entrada. Llama a la bfunción dos veces, que realiza el procesamiento real de acuerdo con las especificaciones.
Demostración aquí .
Probándolo

l=[("abc bab", "abdabc"),
("abcde", "abcd bcde"),
("hello test", "test banana"),
("birds flying high", "whistling high nerds")]
for e in l:
    print m(*e)

SALIDAS:

('cba bba', 'badcba')
('dcbae', 'dcba edcb')
('hello tset', 'tset banana')
('bisdr flyhgih gni', 'wihstlhgih gni nesdr')

PD: Gracias a orlp por la solución usando next()

Kamehameha
fuente
m=lambda A,B:(b(A,B),b(B,A))
orlp
También se puede reemplazar while len(A)>0con solo while A. Del mismo modo se if len(p)>0convierte if p.
orlp
if len(p)También puede ser if p. (Ya se ha dicho anteriormente, sino que se ha perdido.)
mbomb007
@ mbomb007 No lo leí correctamente. Acabo de reemplazar len(p)>0a len(p). Gracias por eso :)
Kamehameha
Aún más corto: while A:j=next((j for j in range(len(A),0,-1)if A[:j]in B),1);C+=A[:j][::-1];A=A[j:].
orlp