Substitution de séquence

30

La plupart des langues sont livrées avec une fonction intégrée pour rechercher dans une chaîne toutes les occurrences d'une sous-chaîne donnée et remplacer celles-ci par une autre. Je ne connais aucun langage qui généralise ce concept aux sous-séquences (pas nécessairement contiguës). Voilà donc votre tâche dans ce défi.

L'entrée sera composée de trois chaînes A, Bet C, où Bet Csont garantis d'être de la même longueur. Si Bapparaît en tant que sous-séquence, Ail doit être remplacé par C. Voici un exemple simple:

A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345

Il serait traité comme ceci:

abcdefghijklmnopqrstuvwxyz
      ||      |   ||
abcdef12ijklmn3pqr45uvwxyz

S'il existe plusieurs façons de rechercher Bune sous-séquence, vous devez remplacer avidement la plus à gauche:

A: abcdeedcba
B: ada
C: BOB

Result:   BbcOeedcbB
and NOT:  BbcdeeOcbB

La même chose s'applique si elle Bpeut être trouvée dans plusieurs endroits disjoints:

A: abcdeedcbaabcde
B: ed
C: 12

Result:   abcd1e2cbaabcde
and NOT:  abcd112cbaabc2e (or similar)

Lorsque Bn'apparaît pas dans A, vous devez sortir Ainchangé.

Règles

Comme indiqué ci-dessus, prenez trois chaînes A, Bet Ccomme entrée et remplacez l'occurrence la plus à gauche de Bcomme sous-séquence Aavec C, s'il y en a.

Vous pouvez écrire un programme ou une fonction, en prenant une entrée via STDIN (ou l'alternative la plus proche), un argument de ligne de commande ou un argument de fonction et en sortant le résultat via STDOUT (ou l'alternative la plus proche), la valeur de retour de la fonction ou le paramètre de la fonction (out).

Vous pouvez prendre les trois chaînes dans n'importe quel ordre cohérent que vous devez spécifier dans votre réponse. Vous pouvez supposer queB et Cavoir la même longueur. Toutes les chaînes ne contiendront que des caractères alphanumériques.

la norme règles de s'appliquent.

Cas de test

Chaque cas de test est de quatre lignes: A, B, Csuivi par le résultat.

abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

abcdeedcba
ada
BOB
BbcOeedcbB

abcdeedcbaabcde
ed
12
abcd1e2cbaabcde

121
121
aBc
aBc

abcde
acb
123
abcde

ABC
ABCD
1234
ABC

012345678901234567890123456789
42
TT
0123T5678901T34567890123456789

edcbaedcbaedcbaedcba
abcde
12345
edcbaedcbaedcbaedcba

edcbaedcbaedcbaedcbaedcba
abcde
12345
edcb1edc2aed3bae4cba5dcba

daccdedca
ace
cra
dcrcdadca

aacbcbabcccaabcbabcaabbbbca
abaaaccbac
1223334444
aacbcbabcccaabcbabcaabbbbca

aacbcbabcccaabcbabcaabbbbcac
abaaaccbac
1223334444
1ac2cb2bccc33b3bab4aa4bbbc44

Classement

L'extrait de pile au bas de cet article génère des classements à partir des réponses a) comme une liste des solutions les plus courtes par langue et b) comme un classement général.

Pour vous assurer que votre réponse s'affiche, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:

## Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les rayant. Par exemple:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Si vous souhaitez inclure plusieurs nombres dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou si vous souhaitez répertorier les pénalités de drapeau d'interprète séparément), assurez-vous que le score réel est le dernier numéro de l'en-tête:

## Perl, 43 + 2 (-p flag) = 45 bytes

Vous pouvez également faire du nom de la langue un lien qui apparaîtra ensuite dans l'extrait de code:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

Martin Ender
la source
Une liste de chaînes de caractères simples conviendrait-elle pour les entrées / sorties?
FryAmTheEggman
@FryAmTheEggman Hm, le seul consensus que je peux trouver est celui-ci qui ne traite pas les listes de chaînes à un caractère comme des représentations de chaînes valides. Cela pourrait valoir la peine de faire un meta post (surtout parce que je pense que cela est également venu sur le dernier défi de xnor). Je vais dire non pour l'instant.
Martin Ender
Qu'en est-il des tableaux de caractères? Cela semble impliquer qu'ils sont autorisés même si la langue a un type de chaîne approprié.
Dennis
@ Dennis Ouais, les tableaux de caractères sont très bien, mais les chaînes singleton sont comme prendre un tableau d'entiers comme [[1], [2], [3]].
Martin Ender
Ok, merci d'avoir éclairci ça.
Dennis

Réponses:

3

Gelée , 23 22 21 octets

='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?

Essayez-le en ligne! Notez que les deux derniers cas de test manqueront de mémoire.

Vérification

$ head -n 5 test-cases
abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

$ cat subseq-short
while read s; do
        read p; read r; read o; echo $o; read
        timeout 1s jelly eun $1 "='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?" "'$s'" "'$p'" "'$r'"
        (($?)) && echo '(killed)'
done < test-cases
$ ./subseq-short
abcdef12ijklmn3pqr45uvwxyz
abcdef12ijklmn3pqr45uvwxyz
BbcOeedcbB
BbcOeedcbB
abcd1e2cbaabcde
abcd1e2cbaabcde
aBc
aBc
abcde
abcde
ABC
ABC
0123T5678901T34567890123456789
0123T5678901T34567890123456789
edcbaedcbaedcbaedcba
edcbaedcbaedcbaedcba
edcb1edc2aed3bae4cba5dcba
edcb1edc2aed3bae4cba5dcba
dcrcdadca
dcrcdadca
aacbcbabcccaabcbabcaabbbbca
(killed)
1ac2cb2bccc33b3bab4aa4bbbc44
(killed)

Comment ça marche

='T€ŒpfṢ€$ḢṬœp³ż⁵$³Ḋ?  Main link. Arguments: string s, pattern p, replacement r

='                     Compare each character of s with each character of p.
                       This yields a 2D list. Each row corresponds to a char in p.
  T€                   Compute the truthy indices of each row, i.e., the indices
                       of all occurrences of that char in s.
   Œp                  Compute the Cartesian product of the lists of indices.
        $              Combine the two links to the left into a monadic chain:
      Ṣ€                 Sort each list of indices.
     f                   Filter, removing all non-sorted lists of indices.
         Ḣ             Head; take the first (sorted) list of indices.
          Ṭ            Truth; generate a list with 1's at those indices.
           œp³         Partition; split s at all 1's, removing those characters.
                  Ḋ?   If the partition has more than more than one element:
              ż⁵$        Zip the partition with r.
                 ³       Else, return s.
Dennis
la source
12

Python 2, 88 octets

def f(a,b,c,o=""):
 for q in a:x=q==b[:1];o+=c[:x]or q;b=b[x:];c=c[x:]
 print[o,a][c>'']

Une fonction qui prend les trois chaînes et renvoie le résultat à STDOUT. La fonction passe simplement sur la chaîne, en prenant le caractère approprié et en mettant b,cà jour au fur et à mesure.

Pour les tests (après avoir remplacé le printpar return):

S = """
<test cases here>
"""

for T in S.split("\n\n"):
    A,B,C,D = T.split()
    assert f(A,B,C) == D
Sp3000
la source
9

Java 7, 141

Je pense que je peux en faire plus, mais je dois courir pour l'instant. C'est juste une simple itération / remplacement, en gardant un index dans A et B.

char[]h(char[]a,char[]b,char[]c){char[]d=a.clone();int i=0,j=0,k=b.length;for(;i<a.length&j<k;i++)if(a[i]==b[j])d[i]=c[j++];return j==k?d:a;}

Espace pour votre plaisir:

char[]h(char[]a,char[]b,char[]c){
    char[]d=a.clone();
    int i=0,j=0,k=b.length;
    for(;i<a.length&j<k;i++)
        if(a[i]==b[j])d[i]=c[j++];
    return j==k?d:a;
}
Géobits
la source
Whitespacedoui, c'est totalement lisible
chat
N'est-ce pas? La raison principale pour laquelle j'ajoute la version en retrait sur plusieurs lignes est d'éviter le défilement horizontal, juste pour que tout soit visible en même temps. L'espace en ligne n'est pas aussi important IMO;)
Geobits
[fonctionnalité-demande] encore plus d'espaces
Alex A.
@AlexA. Voilà!
Geobits
@Geobits Enregistrez un octet à la fin si vous le faitesj<k?a:d
Xanderhall
7

Lua, 121 octets

Solution simple, gsub nous permet d'itérer exactement une fois sur chaque caractère et de les remplacer dans une nouvelle instance de la chaîne.

Il prend l'entrée via 3 arguments de ligne de commande et génère une chaîne vers STDOUT.

a,b,c=...d=a:gsub(".",function(s)if b:find(s)then b=b:sub(2)x=c:sub(1,1)c=c:sub(2)return x end end)print(b~=''and a or d)

Non golfé

a,b,c=...               -- unpack the arguments into a, b and c
d=a:gsub(".",function(s)-- iterate over each character of the first argument
  if b:find(s)then      -- if the current character is in the set b
    b=b:sub(2)          -- remove it from b
    x=c:sub(1,1)        -- save the replacement character in x
    c=c:sub(2)          -- remove it from c
    return x            -- replace the current character with x
  end
end)
print(b~=''             -- if b is empty, we replaced all the character
      and a or d)       -- so output the result of gsub, else, output the first argument
Katenkyo
la source
6

Python 3, 127 octets.

16 octets enregistrés grâce à Katenkyo.

Travaillant toujours un peu dessus, l'homme était plus méchant que je ne le pensais.

f=lambda a,b,c:a.replace(b[0],c[0],1)[:a.index(b[0])+1]+f(a[a.index(b[0])+1:],b[1:],c[1:])if b and all(x in a for x in b)else a

Explication: Awww ouais, récursivité.

Cas de test:

assert f('abcdeedcba', 'ada', 'BOB') == 'BbcOeedcbB'
assert f('abcdeedcbaabcde', 'ed', '12') == 'abcd1e2cbaabcde'
assert f('012345678901234567890123456789', '42', 'TT') == '0123T5678901T34567890123456789'
assert f('ABC', 'ABCD', '1234') == 'ABC'
Morgan Thrapp
la source
+1 pour jouer au golf à 50, mais continuez! Cela doit au moins battre ma réponse Java;)
Geobits
7
@Geobits Oui, je n'ai jamais perdu contre Java auparavant. C'est ma plus grande honte.
Morgan Thrapp
Je ne suis pas vraiment versé en python mais all(x in a for x in b)vérifie également que les éléments en b et a apparaissent dans le même ordre, ou seulement s'ils sont ici?
Katenkyo
@Katenkyo Seulement qu'ils sont tous là, mais l'ordre est pris en charge par le découpage lorsque nous récurons.
Morgan Thrapp
D'accord, cela ne return a.replace(b[0],c[0],1)[:l(b[0])+1]+f(a[l(b[0])+1:],b[1:],c[1:])if b and all(x in a for x in b)else avous ferait-il pas économiser quelques octets?
Katenkyo
5

Python 3.5, 87 octets

import re
lambda s,p,r:re.sub('(.*?)'.join(p),'\g<%d>'.join(r)%(*range(1,len(r)),),s,1)

repl.it pour vérifier tous les cas de test .

Comment ça marche

  • '(.*?)'.join(p) construit un modèle de recherche qui correspond à la sous-séquence à remplacer et à tout ce qui se trouve entre ses éléments.

    Comme les quantificateurs sont paresseux, chacun (.*?) correspondra au moins de caractères possible.

    Pour le modèle ghost, l'expression régulière construite est g(.*?)h(.*?)o(.*?)s(.*?)t.

  • '\g<%d>'.join(r)%(*range(1,len(r)),) construit la chaîne de remplacement, en utilisant le formatage de la chaîne.

    Chacun \g<n>fait référence au n ème groupe capturé, tout comme\n ferait.

    Pour le remplacement 12345, la chaîne construite est 1\g<1>2\g<2>3\g<3>4\g<4>5.

  • re.sub(...,...,s,1)effectue au plus un remplacement dans la chaîne s.

Dennis
la source
4

Pyth, 27

.xuXG.*HC,hSI#.nM*FxRcQ1zwQ

Suite de tests

La suite de tests omet les deux derniers cas car ils manqueront de mémoire. L'algorithme utilisé ici consiste à rechercher tous les indices de chaque caractère dans la deuxième chaîne de la première chaîne, puis à trouver tous les ordres possibles de ces indices et à ne prendre que ceux qui sont triés. Utilisez ensuite le premier de ceux-ci dans l'ordre trié comme liste d'index dans la première chaîne pour mettre à jour avec les valeurs de la troisième chaîne.

Je pense qu'il devrait y avoir quelque chose de plus court que .nM*F...

FryAmTheEggman
la source
4

MATL , 33 octets

y!=[]0b"@n:!<@*fX<h5Mt?}.]]?iw(}x

Essayez-le en ligne!

Explication

y!      % Implicitly input first two strings. Duplicate the first and transpose
=       % Compare the two strings element-wise. Gives a 2D array with all combinations
[]      % Push empty array. Indices of matching elements will be appended to this
0       % Push a 0. This is the index of last character used up in first string
b       % Bubble up (rearrange elements in stack) to move 2D array to top
"       % For each column of that array (each char of the second string)
  @     %   Push current column
  n:!   %   Transform into column array of consecutive values starting from 1
  <     %   Compare with index of last character used up of first string
  @*    %   Push current column again. Multiply element-wise (logical AND)
  fX<   %   Find index of first matching character, or empty if there's none
  h     %   Append to array containing indices of matching elements
  5Mt   %   Push index of matching character again. Duplicate
  ?}    %   If it's empty
    .   %     Break loop
  ]     %   End if
]       % End for
        % The top of the stack now contains a copy of the index of last matching
        % character, or an empty array if there was no match
?       % If non-empty: all characters were matched
  i     %   Input third string
  w     %   Swap top two elements in stack
  (     %   Assign the characters of the third string to first string at found indices
}       % Else: the original string needs to be output
  x     %   Delete (partial) array of matching indices. Leave original string in stack
        % End if
        % Implicitly display (either modified string or original string)
Luis Mendo
la source
3

JavaScript (ES6), 84 octets

(a,b,c)=>[...b].every((q,i)=>r[p=a.indexOf(q,p)]=~p++&&c[i],p=0,r=[...a])?r.join``:a

Explication / test

user81655
la source
3

JavaScript (ES6), 84 76 octets

(a,b,c)=>a.replace(RegExp([...b].join`(.*?)`),c.replace(/\B/g,(_,i)=>'$'+i))

Parce que j'étais sûr que c'était un travail pour RegExp.

Edit: 8 octets enregistrés grâce à @ MartinBüttner ♦.

Un port de la réponse Ruby de @ KevinLau a pris 82 octets:

([...a],[...b],[...c])=>(d=a.map(e=>e==b[0]?c.shift(b.shift()):e),b[0]?a:d).join``

J'ai également essayé une solution RegExp récursive mais qui a pris 90 octets:

f=(a,[b,...d],[c,...e])=>b?a.replace(RegExp(b+'(.*'+d.join`.*`+'.*)'),(_,s)=>c+f(s,d,e)):a
Neil
la source
3

Julia, 89 70 octets

f(s,a,b,i=0)=(o=join(["$a "[i+1]!=c?c:b[i+=1]for c=s]);i<endof(a)?s:o)

Utilise un index ipour parcourir les chaînes de modèle / remplacement au fur et à mesure. -19 octets grâce à @Dennis!

Sp3000
la source
2

C, 98 octets

char*f(i,o,s,r)char*i,*o,*s,*r;{char*I=i,*O=o;for(;*i;++i,++o)*o=*i==*s?++s,*r++:*i;return*s?I:O;}

/ * Code développé * /

char *f(i, o, s, r)
    char *i, *o, *s, *r;
{
    char *I=i, *O=o;
    for (;  *i;  ++i,++o)
        *o = (*i==*s) ? (++s,*r++) : *i;
    return *s ? I : O;
}

Les arguments sont: i nput chaîne, o tampon utput, s chaîne echerchez, r eplacement.

Après avoir mémorisé le début de l'entrée et de la sortie, nous parcourons l'entrée, remplaçant et avançant la substitution chaque fois que nous en frappons une. À la fin, si nous n'avons plus de substitutions, renvoyez le tampon de sortie, sinon l'entrée non modifiée.

/ * Tests * /

struct T
{
    const char *input;
    const char *search;
    const char *replace;
    const char *expected;
};

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int i;
    static const struct T test[] = {
        { "abcdefghijklmnopqrstuvwxyz",
          "ghost",
          "12345",
          "abcdef12ijklmn3pqr45uvwxyz"},
        { "abcdeedcba",
          "ada",
          "BOB",
          "BbcOeedcbB"},
        { "abcdeedcbaabcde",
          "ed",
          "12",
          "abcd1e2cbaabcde"},
        { "121",
          "121",
          "aBc",
          "aBc"},
        { "abcde",
          "acb",
          "123",
          "abcde"},
        { "ABC",
          "ABCD",
          "1234",
          "ABC"},
        { "012345678901234567890123456789",
          "42",
          "TT",
          "0123T5678901T34567890123456789"},
        { "edcbaedcbaedcbaedcba",
          "abcde",
          "12345",
          "edcbaedcbaedcbaedcba"},
        { "edcbaedcbaedcbaedcbaedcba",
          "abcde",
          "12345",
          "edcb1edc2aed3bae4cba5dcba"},
        { "daccdedca",
          "ace",
          "cra",
          "dcrcdadca"},
        { "aacbcbabcccaabcbabcaabbbbca",
          "abaaaccbac",
          "1223334444",
          "aacbcbabcccaabcbabcaabbbbca"},
        { "aacbcbabcccaabcbabcaabbbbcac",
          "abaaaccbac",
          "1223334444",
          "1ac2cb2bccc33b3bab4aa4bbbc44"
        }
    };

    for (i = 0;  i < (sizeof test) / (sizeof test[0]);  ++i) {
        const struct T *t = test+i;
        char *out = malloc(strlen(t->input)+1);
        char *result = f(t->input, out, t->search, t->replace);
        if (strcmp(t->expected, result))
            printf("Failed test %d; result = \"%s\"\n", i, result);
    }
    return EXIT_SUCCESS;
}
Toby Speight
la source
2

R, 76 octets

function(a,b,c){s=substr;for(x in 1:nchar(b)){a=sub(s(b,x,x),s(c,x,x),a)};a}

utilise subpour remplacer la première correspondance

Non golfé

function(a,b,c){                    # function with 3 arguments as per description
  s=substr;                         # alias for substr (saves 1 byte)
   for(x in 1:nchar(b)){            # index 1 to number character in b
     a=sub(s(b,x,x),s(c,x,x),a)};   # replace first instance of b[x] in a  
                                    # with c[x] and reassign to a
 a}                                 # return a
mnel
la source
2

C ++, 204 octets

Golfé

#include<iostream>
#include<string>
int main(){std::string a, b, c;std::cin>>a>>b>>c;int t=0;for(int x=0;x<b.length();x++){t=a.find(b[x],t);if(t!=-1){a.replace(t,1,c.substr(x,1));}}std::cout<<a;return 0;}

Non golfé

#include<iostream>
#include<string>

int main()
{
    std::string a, b, c;
    std::cin>>a>>b>>c;
    int t = 0;
    for (int x=0;x<b.length();x++) {
        t = a.find(b[x], t);
        if (t != -1) {
            a.replace(t,1,c.substr(x, 1));
        }
    }
    std::cout<<a;
    return 0;
}
Michelfrancis Bustillos
la source
Je ne pense pas que vous en utilisiez stdassez pour justifier l'utilisation using namespace std;. L'utilisation de std::cin, std::coutet std::stringéconomisera 5 octets, car ceux-ci semblent être les seules utilisations de cet espace de noms.
Value Ink
@KevinLau Merci! Vous avez tout à fait raison, j'y ai pensé, mais cela ne comptait pas vraiment pour réaliser que cela sauverait des caractères.
Michelfrancis Bustillos
Oh! Encore une chose, car c'est important. Après avoir relu votre code, je me suis rendu compte que vous remplaçiez goulûment l'occurrence la plus à gauche de chaque lettre à l'intérieur bde a, mais les dernières lettres doivent également être postérieures aux premières. (Regardez le cas de test 3 et comparez avec votre sortie, je pense que vous constaterez que votre code sortirait abc21ed...quand la sortie attendue est abcd1e2...!)
Value Ink
Dans le compilateur ideone C ++ 14 du code "Adregffftd \ nA23 \ nzac \ n" ci-dessus il y a 10 minutes, générez la sortie de "zdregffftd" au lieu de "Adregffftd"
RosLuP
2

Rétine , 63 octets

.+$
$&¶;$&
+`^(.)(.*¶)(.)([^;]+);(.*?)\1
$2$4$5$3;
A1`
;

G2=`.

L'entrée est prise dans l'ordre B , C,A , séparés par des sauts de ligne.

Essayez-le en ligne.

Martin Ender
la source
2

Haskell, 87 octets

x@((a,b):c)#(d:e)|a==d,([],z)<-c#e=([],b:z)|0<1=(d:)<$>x#e
x#y=(x,y)
a!b=snd.(zip a b#)

J'ai remarqué l'absence de réponse Haskell et j'ai décidé de corriger cela. Ceci définit une fonction ternaire! avec une chaîne de remplacement de motif d'ordre des arguments. Essayez-le ici.

Explication

La fonction auxiliaire #prend une liste xde paires de caractères (modèle et remplacement) et une chaîne y. Si les caractères "modèle" xforment une sous-séquence de y, il retourne la liste vide et yavec chaque caractère modèle remplacé par son homologue. Sinon, il renvoie la paire (x,y). La fonction !zippe le modèle et les chaînes de remplacement dans x, s'applique #à xet à la troisième chaîne et renvoie le deuxième composant du résultat.

x@((a,b):c)#(d:e)  -- First case of #: both arguments nonempty.
  |a==d,           -- If the pattern char matches the string's head,
   ([],z)<-c#e     -- and the pattern's tail is a subsequence of the string's tail,
  =([],b:z)        -- tack the replacement char to the recursion result.
  |0<1             -- Otherwise,
  =(d:)<$>x#e      -- recurse with the same pairs and tack string's head to result.
x#y=(x,y)          -- If either argument is empty, just pair them.

Si le modèle est une sous-séquence de la chaîne, le code s'exécute en temps O (n) , effectuant un passage récursif à travers la chaîne et construisant avidement le remplacement dans le processus. Cependant, si le motif n'est pas une sous-séquence, il s'exécute en temps O (2 n ) dans le pire des cas. En effet, à chaque position où le motif et la chaîne ont un caractère correspondant, la fonction s'appelle pour vérifier si le motif est réellement une sous-séquence, découvre que ce n'est pas le cas et s'appelle une deuxième fois pour calculer réellement le résultat.

Zgarb
la source
2

JavaScript (ES6), 100 à 95 octets

(a,b,c)=>1?(t=[...a].map(e=>b[0]==e?(u=c[0],b=b.slice(1),c=c.slice(1),u):e).join``,b==""?t:a):a

Il s'agit d'une fonction Lambda JavaScript valide. Sorties comme fonction return. Prend trois arguments ( a,b,c). Ajoutez f=au début et invoquez comme f(arg1,arg2,arg3).

f=(a,b,c)=>1?(t=[...a].map(e=>b[0]==e?(u=c[0],b=b.slice(1),c=c.slice(1),u):e).join``,b==""?t:a):a

console.log(f(prompt("Value for A"),prompt("Value for B"),prompt("Value for C")))

Arjun
la source
Bienvenue chez PPCG! Les fonctions sans nom sont généralement acceptables , vous n'avez donc pas besoin de f=sauf si votre fonction est récursive, mais elle ne semble pas l'être.
Martin Ender
@ MartinBüttner Merci! :) Mis à jour ma réponse.
Arjun
Malheureusement, cela échouera s'il ane contient pas le modèle. Je ne suis pas sûr non plus que le retour d'un tableau de chaînes soit acceptable.
Dennis
@Dennis J'ai mis à jour ma solution. Je pense que c'est correct maintenant. Désolé pour cette réponse et cette mise à jour tardives. (Je viens de remarquer votre commentaire, d'où le retard)
Arjun
@MartinEnder Pendant que je parcourais toutes mes solutions, j'ai trouvé que celle-ci était incorrecte. Mais, je l'ai corrigé maintenant; et il est cinq octets plus court (puisque j'avais laissé de nombreux terrains de golf intacts; j'étais un golfeur novice à cette époque; pas que je sois grand maintenant, cependant: p). Désolé d'avoir publié une mauvaise solution.
Arjun
2

C (gcc), 67 62 61 59 octets

f(s,a,b)char*s,*a,*b;{*s==*a?*s=*b++,a++:1;*a&&f(s+1,a,b);}

Essayez-le en ligne!

betseg
la source
1

Octave, 97 octets

function A=U(A,B,C)t=0;for s=B if p=find(A(t+1:end)==s,1) D(t=p+t)=~0;else return;end;end;A(D)=C;

Itérer sur la sous-séquence à remplacer; rechercher la première occurrence du premier caractère, rechercher le caractère suivant dans la chaîne restante, répéter. Le seul élément intéressant de ceci est:

D(t=p+t)=~0

D(     )      %// D is a logical mask of characters to replace in the input string
  t=p+t       %// t is the current end of D 
              %// p is the location of the character to replace
              %// update t and use as index to grow D
        =~0   %// make it so, number 1

Comme ideone n'accepte toujours pas les fonctions avec des noms autres que '', je vais laisser un exemple ici. Par souci de concision, les entrées ne sont affichées que pour les premiers cas de test. keyest la sortie attendue, ansest la sortie de la fonction.

A = abcdefghijklmnopqrstuvwxyz
B = ghost
C = 12345
key = abcdef12ijklmn3pqr45uvwxyz
ans = abcdef12ijklmn3pqr45uvwxyz
A = abcdeedcba
B = ada
C = BOB
key = BbcOeedcbB
ans = BbcOeedcbB
A = abcdeedcbaabcde
B = ed
C = 12
key = abcd1e2cbaabcde
ans = abcd1e2cbaabcde
key = aBc
ans = aBc
key = abcde
ans = abcde
key = ABC
ans = ABC
key = 0123T5678901T34567890123456789
ans = 0123T5678901T34567890123456789
key = edcbaedcbaedcbaedcba
ans = edcbaedcbaedcbaedcba
key = edcb1edc2aed3bae4cba5dcba
ans = edcb1edc2aed3bae4cba5dcba
key = dcrcdadca
ans = dcrcdadca
key = aacbcbabcccaabcbabcaabbbbca
ans = aacbcbabcccaabcbabcaabbbbca
key = 1ac2cb2bccc33b3bab4aa4bbbc44
ans = 1ac2cb2bccc33b3bab4aa4bbbc44
gobelet
la source
Ces missions d'octave dans des endroits inattendus ( D(t=...)) continuent de me intriguer :-)
Luis Mendo
1
@LuisMendo haha ​​... c'est presque comme ... une pile! :)
bécher
1

Python 3, 123 octets

Une approche différente que je voulais partager, qui est plus courte de quelques octets. Il n'y a pas de règles contre les bibliothèques / expressions régulières standard, non?

import re
j=''.join
m='(.*?)'
def f(A,B,C):
 *r,l=(re.findall(m+m.join(B)+'(.*)',A)or[[A]])[0]
 print(j(map(j,zip(r,C)))+l)

PS. Ceci est mon premier golf. Faites-moi part de tout problème / amélioration.

Marc J
la source
1

Pyth, 22 octets

|eJ:Ej"(.*?)"+E\$3s.iJ

Vérifiez tous les cas de test dans le compilateur Pyth .

Contexte

Nous construisons une expression régulière à partir du modèle en ajoutant un $et en plaçant(.*?) entre tous les caractères. Cette expression régulière fera correspondre la sous-séquence à remplacer et tout ce qui se trouve entre ses éléments, et tout ce qui se trouve jusqu'à la fin de la chaîne.

Étant donné que les quantificateurs sont paresseux, chacun(.*?) correspondra au moins de caractères possible.

Pour le fantôme modèle, l'expression régulière construite est g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$.

Si le modèle correspond à l'entrée, la fonction intégrée r<str><regex>3renverra un tableau contenant le prématch (tout avant la sous-séquence), tous les groupes capturés (tout entre et après la sous-séquence) et le postmatch (la chaîne vide).

Si le modèle ne correspond pas, la fonction intégrée renverra un tableau singleton contenant l'entrée d'origine.

Comment ça marche

|eJ:Ej"(.*?)"+E\$3s.iJQ  (implicit) Store the first line of input in Q.

             +E\$        Read the third line of input (pattern) and append '$'.
     j"(.*?)"            Join the result, separating by "(.*?)".
    E                    Read the third line of input (string).
   :             3       Match the string against the regex, as detailed above.
  J                      Save the returned array in J.
 e                       Extract the last element of J. This is an empty string
                         for a successful match or the original string.
|                        Logical OR; replace an empty string with the following:
                   .iJQ    Interleave J and the replacement.
                  s        Flatten the resulting array of strings.
Dennis
la source
1

Gelée , 23 octets

Ṭœpż⁵
0ẋai1
⁴='-;ç\ñ⁴P?

C'est deux octets de plus que mon autre réponse Jelly , mais cela se termine instantanément.Essayez-le en ligne!

Vérification

$ head -n 5 test-cases
abcdefghijklmnopqrstuvwxyz
ghost
12345
abcdef12ijklmn3pqr45uvwxyz

$ cat subseq-fast
while read s; do
        read p; read r; read o; echo $o; read
        timeout 10s jelly eun $1 "Ṭœpż⁵¶0ẋai1¶⁴='-;ç\ñ⁴P?" "'$p'" "'$s'" "'$r'"
        (($?)) && echo '(killed)'
done < test-cases
$ ./subseq-fast
abcdef12ijklmn3pqr45uvwxyz
abcdef12ijklmn3pqr45uvwxyz
BbcOeedcbB
BbcOeedcbB
abcd1e2cbaabcde
abcd1e2cbaabcde
aBc
aBc
abcde
abcde
ABC
ABC
0123T5678901T34567890123456789
0123T5678901T34567890123456789
edcbaedcbaedcbaedcba
edcbaedcbaedcbaedcba
edcb1edc2aed3bae4cba5dcba
edcb1edc2aed3bae4cba5dcba
dcrcdadca
dcrcdadca
aacbcbabcccaabcbabcaabbbbca
aacbcbabcccaabcbabcaabbbbca
1ac2cb2bccc33b3bab4aa4bbbc44
1ac2cb2bccc33b3bab4aa4bbbc44

Comment ça marche

⁴='-;ç\ñ⁴P?  Main link. Arguments: pattern p, string s, replacement r

⁴='          Compare each character of s with each character of p.
             This yields a 2D list. Each row corresponds to a char in p.
   -;        Prepend -1 to the 2D list, yielding a ragged array.
     ç\      Cumulatively reduce the array by the second helper link.
         P?  If the product of the resulting list is non-zero:
       ñ       Call the first helper link with the list and s as arguments.
        ⁴      Else, return s.


Ṭœpż⁵        First helper link. Arguments: L (list of indices), r (replacement)

Ṭ            Truth; generate a list with 1's at those indices.
 œp          Partition; split s at all 1's, removing those characters.
   ż⁵        Zip the partition with r.


0ẋai1        Second helper link. Arguments: n (integer), B (list of Booleans)

0ẋ           Generate a list of n zeroes.
  a          Perform logical AND with B.
             This zeroes out the with n elements of B.
   i1        Compute the first index of 1.
Dennis
la source
1

Java 7, 102 octets

void L(char[]s,char[]l,char[]r){for(int x=0,y=0;x<s.length&&y<l.length;x++)if(s[x]==l[y])s[x]=r[y++];}

Essai détaillé ici

// String, Lookup, Replacement
void L(char[]s, char[]l, char[]r)
{
    for(int x=0, y=0; x < s.length && y < l.length; x++)
        if(s[x] == l[y])
            s[x] = r[y++];
}
Khaled.K
la source
1

Julia, 93 90 86 octets

f(s,p,r)=(try s=join([match(Regex(join("^$p\$","(.*?)")),s).captures';[r...""]])end;s)

Devoir tester séparément si le match a réussi détruit un peu le score. Une substitution nécessiterait un casting Base.SubstitutionString, ce qui n'en vaut probablement pas la peine ...

Essai

julia> f(s,p,r)=(try s=join([match(Regex(join("^$p\$","(.*?)")),s).captures';[r...""]])end;s)
f (generic function with 1 method)

julia> f("aacbcbabcccaabcbabcaabbbbca","abaaaccbac","1223334444")
"aacbcbabcccaabcbabcaabbbbca"

julia> f("aacbcbabcccaabcbabcaabbbbcac","abaaaccbac","1223334444")
"1ac2cb2bccc33b3bab4aa4bbbc44"
Dennis
la source
1

Julia, 62 59 58 octets

f(s,p,r)=(try s[[i=findnext(s,c,i+1)for c=p]'],i=r,0end;s)

Les E / S se présentent sous la forme de tableaux de caractères.

Vérification

julia> f(s,p,r)=(try s[[i=findnext(s,c,i+1)for c=p]'],i=r,0end;s)
f (generic function with 2 methods)

julia> F(s,p,r)=join(f([s...],[p...],[r...])) # string/char array conversion
F (generic function with 1 method)

julia> F("aacbcbabcccaabcbabcaabbbbca","abaaaccbac","1223334444")
"aacbcbabcccaabcbabcaabbbbca"

julia> F("aacbcbabcccaabcbabcaabbbbcac","abaaaccbac","1223334444")
"1ac2cb2bccc33b3bab4aa4bbbc44"
Dennis
la source
1

PHP, 130 109 octets

Je l'aimerais encore plus court; pourrait enregistrer 3 octets ( ""<) s'il Bétait garanti de ne pas contenir 0.

for($s=($a=$argv)[1];""<$c=$a[2][$i++];)if($p=strpos(_.$s,$c,$p+1))$s[$p-1]=$a[3][$k++];echo$k<$i-1?$a[1]:$s;

prend les arguments de la ligne de commande. Courez avec -r.

Remplace les personnages lorsqu'il les trouve;
imprime une copie si tous les caractères ont été remplacés; original autrement.

Titus
la source
1

Rubis, 70 64 59 58 octets

Fonction anonyme. Parcourez la chaîne apour créer une nouvelle chaîne avec des lettres remplacées conformément au caractère suivant dans betc , alors si tous les caractères bsont épuisés à la fin, le retour de la chaîne nouvellement construit, sinon retourner la chaîne d' origine.

@histocrat a permis d'économiser 6 octets via gsub .

1 octet enregistré grâce à @Cyoce.

->a,b,c{i=0;s=a.gsub(/./){$&==b[i]?c[~-i+=1]:$&};b[i]?a:s}

Essayez-le en ligne!

Encre de valeur
la source
Vous pouvez enregistrer un octet en le remplaçant -1+i+=1par~-i+=1
Cyoce
0

Perl, 80 + 1 = 81 octets

Courir avec le -pdrapeau

$a=join"(.*?)",split//,<>;$b.=$_." .\$".++$;."."for split//,<>;chop$b;s/$a/$b/ee

Essayez-le en ligne!

Le code génère de manière procédurale une commande de recherche et de remplacement de regex, qu'il exécute ensuite dans le dernier bit de code.

La chaîne ghostdu premier exemple est transformée en chaîne g(.*?)h(.*?)o(.*?)s(.*?)t(.*?), ce qui signifie un gsuivi de 0 ou plusieurs caractères, suivi d'un hsuivi de 0 ou plusieurs caractères, suivi de etc. Le *?quantificateur signifie que la recherche doit être non gourmande et "engloutir" "le moins de caractères possible, au lieu de la valeur par défaut de correspondance autant que possible.

La chaîne est 12345ensuite transformée en 1 .$1.2 .$2.3 .$3.4 .$4.5 .$5, qui est évaluée après l'exécution de l'expression régulière. Chacun $1,$2,$3,$4,$5est en fait une référence arrière à un groupe de capture (entre parenthèses) à partir de la première chaîne.

Gabriel Benamy
la source
Je suggère ce code pour enregistrer quelques octets: perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'. Je l'ai rencontré moi-même, mais il est assez proche du vôtre, donc je ne le posterai pas, ce serait deux réponses très proches, mais n'hésitez pas à modifier le vôtre!
Dada
Je viens juste de l'essayer parce que je l'ai vu répertorié comme une question "connexe" à un problème récent. Le mieux que j'ai eu étaitperl -E 'chomp(($f,$t,$s)=(<>));$f=join"(.*?)",split"",$f;@r=split"",$t;@t=shift@r;push@t,"\${",++$x,"}"for(@r);$t=join"",@t;say$s=~s/$f/$t/r;'
Will Crawford
0

Clojure, 113 octets

#(apply str((reduce(fn[[b c r]a](if(=(first b)a)[(rest b)(rest c)(conj r(first c))][b c(conj r a)]))[%2%3[]]%)2))

Une base reduce, pas trop content de tous les temps first, restet les conjappels de fonction. Espérant voir une meilleure approche.

NikoNyrh
la source