Une relation à l'envers

10

Écrivez un programme ou une fonction qui, étant donné deux chaînes ASCII Aet B, produira des chaînes A'et B'où les sous-chaînes communes sont inversées à leur place. Le processus de recherche A'est le suivant:

  1. A' est initialement vide.
  2. Si le premier caractère de Aest dans B, recherchez le préfixe le plus long Aqui est une sous-chaîne de B. Supprimez ce préfixe de Aet ajoutez son inversion à A'.
  3. Sinon, supprimez ce premier caractère Aet ajoutez-le à A'.
  4. Répétez les étapes 2-3 jusqu'à ce qu'il Asoit vide.

La recherche B'se fait de la même manière.

Exemple

Examinons les chaînes A = "abc bab"et B = "abdabc". Car A'c'est ce qui se passe:

  • A = "abc bab": Le premier caractère "a"est en B et le préfixe le plus long de A trouvé en B est "abc". Nous supprimons ce préfixe de A et ajoutons son inversion "cba"à A '.
  • A = " bab": Le premier caractère " "n'est pas en B, donc nous supprimons ce caractère de A et l'ajoutons à A '.
  • A = "bab": Le premier caractère "b"est en B et le préfixe le plus long de A trouvé en B est "b". Nous supprimons ce préfixe de A et ajoutons son inversion (qui est toujours "b") à A '.
  • A = "ab": Le premier caractère "a"est en B et le préfixe le plus long de A trouvé en B est "ab". Nous supprimons ce préfixe de A et ajoutons son inversion "ba"à A '.
  • A = "": A est vide, alors nous nous arrêtons.

Ainsi nous obtenons A' = "cba" + " " + "b" + "ba" = "cba bba". Pour B ', le processus est similaire:

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

Ainsi nous obtenons B' = "ba" + "d" + "cba" = "badcba".

Enfin, nous renvoyons les deux chaînes, c'est-à-dire

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

Cas de test

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

Le code le plus court en octets gagne.

orlp
la source
Supposons-nous que toutes les entrées sont en ASCII minuscule? La sortie exacte devrait-elle s'apparenter à l' "cba bba", "badcba"inclusion de guillemets et de virgules?
AdmBorkBork
@TimmyD Le format d'entrée / sortie exact est votre choix. Vous ne pouvez pas présumer que l'entrée est en ASCII en minuscules - il peut s'agir de n'importe quel ASCII imprimable.
orlp
La chaîne vide est-elle une entrée légale?
MtnViewMark
@MtnViewMark Oui.
orlp

Réponses:

1

Pyth, 29 octets

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

Harnais de test.

Le format d'entrée est:

abc bab
"abdabc"

La sortie est:

cba bba
badcba
isaacg
la source
2

Haskell, 120 111 octets

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

Essais:

λ: "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
la source
1

SWI-Prolog, 312 octets

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

Exemple: a("birds flying high","whistling high nerds",X,Y).sorties

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

Une solution bien trop longue qui va trop montrer à quel point Prolog est verbeux lorsqu'il s'agit de chaînes. Il pourrait être possible de raccourcir cette chose en utilisant des tableaux de codes ( `birds flying high`) au lieu de chaînes ( "birds flying high").

Fatalize
la source
1

Python 2.7, 169 156 152 141 octets

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 fonction mprend les 2 chaînes en entrée, elle appelle bdeux fois la fonction qui effectue le traitement réel selon les spécifications.
Démo ici .
Le tester -

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

LES SORTIES:

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

PS: Merci à orlp pour la solution utilisant next()

Kamehameha
la source
m=lambda A,B:(b(A,B),b(B,A))
orlp
Vous pouvez également remplacer while len(A)>0par juste while A. De même if len(p)>0devient if p.
orlp
if len(p)peut aussi l'être if p. (Déjà dit ci-dessus, mais vous l'avez manqué.)
mbomb007
@ mbomb007 Je ne l'ai pas lu correctement. Juste remplacé len(p)>0à len(p). Merci pour ça :)
Kamehameha
Encore plus court: 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