Relacja wsteczna

10

Napisz program lub funkcję, która, biorąc pod uwagę dwa łańcuchy ASCII Ai B, wygeneruje łańcuchy A'i B'gdzie wspólne podciągi są odwrócone w ich miejsce. Proces wyszukiwania A'jest następujący:

  1. A' jest początkowo pusty.
  2. Jeśli pierwszy znak Ajest w B, znajdź najdłuższy przedrostek, Aktórego jest podłańcuchem B. Usuń ten prefiks z Ai dodaj jego odwrócenie do A'.
  3. W przeciwnym razie usuń ten pierwszy znak z Ai dodaj go do A'.
  4. Powtarzaj kroki 2-3, aż Abędzie pusty.

Znalezienie B'odbywa się podobnie.

Przykład

Rozważmy ciągi A = "abc bab"i B = "abdabc". Bo A'tak się dzieje:

  • A = "abc bab": Pierwszy znak "a"znajduje się w B, a najdłuższy prefiks A w B to "abc". Usuwamy ten prefiks z A i dodajemy jego odwrócenie "cba"do A '.
  • A = " bab": Pierwszy znak " "nie znajduje się w B, więc usuwamy ten znak z A i dodajemy go do A '.
  • A = "bab": Pierwszy znak "b"znajduje się w B, a najdłuższy prefiks A w B to "b". Usuwamy ten prefiks z A i dodajemy jego odwrócenie (które jest nadal "b") do A '.
  • A = "ab": Pierwszy znak "a"znajduje się w B, a najdłuższy prefiks A w B to "ab". Usuwamy ten prefiks z A i dodajemy jego odwrócenie "ba"do A '.
  • A = "": A jest puste, więc przestajemy.

Tak otrzymujemy A' = "cba" + " " + "b" + "ba" = "cba bba". W przypadku B 'proces jest podobny:

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

Tak otrzymujemy B' = "ba" + "d" + "cba" = "badcba".

Na koniec zwracamy dwa ciągi, tj

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

Przypadki testowe

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

Najkrótszy kod w bajtach wygrywa.

orlp
źródło
Czy zakładamy, że wszystkie dane wejściowe są małymi literami ASCII? Czy oczekiwane dokładne wyniki będą podobne do "cba bba", "badcba"cytowań i przecinków?
AdmBorkBork
@ TimmyD Dokładny format wejścia / wyjścia jest twoim wyborem. Nie można zakładać, że wejście zawiera małe litery ASCII - może to być dowolny drukowany ASCII.
orlp
Czy pusty ciąg jest legalnym wkładem?
MtnViewMark
@MtnViewMark Tak.
orlp

Odpowiedzi:

1

Pyth, 29 bajtów

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

Uprząż testowa.

Format wejściowy to:

abc bab
"abdabc"

Dane wyjściowe to:

cba bba
badcba
isaacg
źródło
2

Haskell, 120 111 bajtów

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

Przebiegi testowe:

λ: "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
źródło
1

SWI-Prolog, 312 bajtów

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

Przykład: a("birds flying high","whistling high nerds",X,Y).wyjścia

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

Droga, droga zbyt długa rozwiązanie, które pokazują, jak idzie zbyt rozwlekły Prolog jest gdy ma do czynienia ze strun. Może być możliwe skrócenie tej rzeczy za pomocą tablic kodów ( `birds flying high`) zamiast strings ( "birds flying high").

Fatalizować
źródło
1

Python 2.7, 169 156 152 141 bajtów

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

Funkcja mprzyjmuje 2 łańcuchy jako dane wejściowe i wywołuje bfunkcję dwukrotnie, co powoduje faktyczne przetwarzanie zgodnie ze specyfikacją.
Demo tutaj .
Testowanie -

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

WYJŚCIA:

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

PS: Dzięki orlp za rozwiązanie next()

Kamehameha
źródło
m=lambda A,B:(b(A,B),b(B,A))
orlp
Możesz też wymienić na while len(A)>0just while A. Podobnie if len(p)>0staje się if p.
orlp
if len(p)może być również if p. (Już powiedziałem wyżej, ale przegapiłeś to.)
mbomb007
@ mbomb007 Nie przeczytałem go poprawnie. Wystarczy wymienić len(p)>0się len(p). Dzięki za to :)
Kamehameha
Nawet krócej: 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