การทดแทนในภายหลัง


30

ภาษาส่วนใหญ่จะมีบิวด์อินเพื่อค้นหาสตริงสำหรับการเกิดขึ้นทั้งหมดของซับสตริงที่กำหนดและแทนที่ด้วยสตริงอื่น ฉันไม่รู้ภาษาใด ๆ ที่ทำให้แนวคิดนี้เป็นจริง (ไม่จำเป็นต้องต่อเนื่องกัน) นั่นคือภารกิจของคุณในการท้าทายนี้

การป้อนข้อมูลจะประกอบด้วยสามสายA, BและCที่BและCมีการรับประกันที่มีความยาวเดียวกัน หากBปรากฏเป็น subsequence ในมันควรจะถูกแทนที่ด้วยA Cนี่คือตัวอย่างง่ายๆ:

A: abcdefghijklmnopqrstuvwxyz
B: ghost
C: 12345

มันจะถูกประมวลผลเช่นนี้:

abcdefghijklmnopqrstuvwxyz
      ||      |   ||
abcdef12ijklmn3pqr45uvwxyz

หากมีหลายวิธีในการค้นหาBให้เป็นลำดับคุณควรแทนที่ด้านซ้ายสุดอย่างโลภ:

A: abcdeedcba
B: ada
C: BOB

Result:   BbcOeedcbB
and NOT:  BbcdeeOcbB

เช่นเดียวกันหากBพบได้ในหลาย ๆ ที่:

A: abcdeedcbaabcde
B: ed
C: 12

Result:   abcd1e2cbaabcde
and NOT:  abcd112cbaabc2e (or similar)

เมื่อBไม่ปรากฏขึ้นAคุณควรเอาท์พุทAไม่เปลี่ยนแปลง

กฎระเบียบ

ตามที่ระบุไว้ข้างต้นใช้เวลาสามสายA, BและCเป็น input และแทนที่เกิดขึ้นซ้ายส่วนใหญ่Bเป็น subsequence ในAด้วยCหากมีการใด ๆ

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

คุณอาจใช้สามสายในลำดับที่สอดคล้องกันซึ่งคุณควรระบุในคำตอบของคุณ คุณอาจจะคิดว่าBและCมีความยาวเดียวกัน สตริงทั้งหมดจะประกอบด้วยตัวอักษรและตัวเลขเท่านั้น

ใช้กฎมาตรฐานของ

กรณีทดสอบ

กรณีทดสอบแต่ละสี่บรรทัด: A, B, Cตามด้วยผล

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

ลีดเดอร์บอร์ด

สแต็คส่วนย่อยที่ด้านล่างของโพสต์นี้สร้างกระดานผู้นำจากคำตอบ a) เป็นรายการของวิธีแก้ปัญหาที่สั้นที่สุดต่อภาษาและ b) เป็นกระดานแต้มนำโดยรวม

เพื่อให้แน่ใจว่าคำตอบของคุณปรากฏขึ้นโปรดเริ่มคำตอบด้วยหัวข้อโดยใช้เทมเพลต Markdown ต่อไปนี้:

## Language Name, N bytes

ที่Nมีขนาดของส่งของคุณ หากคุณปรับปรุงคะแนนของคุณคุณสามารถเก็บคะแนนเก่าไว้ในพาดหัวโดยการตีพวกเขาผ่าน ตัวอย่างเช่น

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

หากคุณต้องการรวมหลายตัวเลขไว้ในส่วนหัวของคุณ (เช่นเนื่องจากคะแนนของคุณคือผลรวมของสองไฟล์หรือคุณต้องการแสดงรายการการลงโทษการตั้งค่าสถานะของล่ามแยกต่างหาก) ตรวจสอบให้แน่ใจว่าคะแนนจริงเป็นตัวเลขสุดท้ายในส่วนหัว:

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

คุณยังสามารถตั้งชื่อภาษาให้เป็นลิงค์ซึ่งจะปรากฏในตัวอย่างข้อมูล:

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


รายการของสตริงอักขระเดียวจะไม่เป็นผลสำหรับอินพุต / เอาต์พุตหรือไม่
FryAmTheEggman

@FryAmTheEggman หืมฉันทามติเดียวที่ฉันสามารถค้นหาได้คือสิ่งนี้ซึ่งไม่ได้ระบุรายการของสตริงอักขระเดี่ยวเป็นการแทนค่าสตริงที่ถูกต้อง อาจจะคุ้มค่าที่จะสร้างเมตาโพสต์ (โดยเฉพาะอย่างยิ่งเพราะฉันคิดว่านี่เป็นความท้าทายล่าสุดของ xnor ด้วย) ฉันจะบอกว่าไม่ตอนนี้
Martin Ender

แล้วอาร์เรย์อักขระล่ะ สิ่งนี้ดูเหมือนว่าพวกเขาได้รับอนุญาตแม้ว่าภาษาจะมีประเภทสตริงที่เหมาะสม
เดนนิส

@Dennis Yeah อาเรย์ของตัวละครดี แต่สตริงซิงเกิลก็เหมือนกับการใช้อาร์เรย์ของจำนวนเต็มเช่น[[1], [2], [3]]กัน
Martin Ender

โอเคขอบคุณสำหรับการล้างข้อมูล
เดนนิส

คำตอบ:


3

เยลลี่ , 23 22 21 ไบต์

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

ลองออนไลน์! โปรดทราบว่ากรณีทดสอบสองครั้งล่าสุดจะมีหน่วยความจำไม่เพียงพอ

การตรวจสอบ

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

มันทำงานอย่างไร

='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.

12

Python 2, 88 ไบต์

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>'']

ฟังก์ชันที่รับสามสตริงและส่งผลลัพธ์ให้กับ STDOUT ฟังก์ชั่นเพียงแค่หนึ่งผ่านสายอักขระการถ่านที่เหมาะสมและปรับปรุงb,cตามที่เราไป

สำหรับการทดสอบ (หลังจากแทนที่printด้วยreturn):

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

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

9

Java 7, 141

ฉันคิดว่ายังมีอะไรอีกบ้างที่ฉันสามารถทำได้ แต่ตอนนี้ฉันต้องรีบแล้ว มันเป็นเพียงการวนซ้ำ / แทนที่ง่าย ๆ โดยเก็บดัชนีไว้ใน A และ 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;}

whitespaced เพื่อความสุขของคุณ:

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;
}

Whitespacedใช่มันอ่านได้ทั้งหมด
แมว

ไม่ใช่เหรอ เหตุผลหลักที่ฉันเพิ่มเวอร์ชันการเยื้องหลายบรรทัดคือเพื่อหลีกเลี่ยงการเลื่อนในแนวนอนเพื่อให้สามารถมองเห็นได้ในครั้งเดียว ช่องว่างแบบอินไลน์ไม่ได้เป็นเรื่องใหญ่มากนัก IMO;)
Geobits

[คำขอคุณลักษณะ] ช่องว่างมากขึ้น
Alex A.


@Geobits บันทึก byte ท้ายที่สุดถ้าคุณทำj<k?a:d
Xanderhall

7

Lua, 121 ไบต์

ทางออกที่ตรงไปตรงมา gsubช่วยให้เราสามารถวนซ้ำหนึ่งครั้งในแต่ละอักขระและแทนที่พวกเขาในอินสแตนซ์ใหม่ของสตริง

ใช้อินพุตผ่านอาร์กิวเมนต์บรรทัดคำสั่ง 3 รายการและส่งออกสตริงไปยัง 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)

Ungolfed

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

6

Python 3, 127 ไบต์

บันทึกแล้ว 16 ไบต์ขอบคุณ Katenkyo

ยังทำงานอยู่นี้นิดหน่อยผู้ชายคนนี้น่ารังเกียจกว่าที่ฉันคิดไว้

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

คำอธิบาย: Awww ใช่การเรียกซ้ำ

กรณีทดสอบ:

assert f('abcdeedcba', 'ada', 'BOB') == 'BbcOeedcbB'
assert f('abcdeedcbaabcde', 'ed', '12') == 'abcd1e2cbaabcde'
assert f('012345678901234567890123456789', '42', 'TT') == '0123T5678901T34567890123456789'
assert f('ABC', 'ABCD', '1234') == 'ABC'

+1 สำหรับการเล่นกอล์ฟ 50 off แต่ไปต่อ! ความต้องการนี้จะชนะคำตอบ Java ของฉันอย่างน้อย;)
Geobits

7
@Geobits ใช่ฉันไม่เคยแพ้กับ Java มาก่อน นี่คือความอัปยศที่ยิ่งใหญ่ที่สุดของฉัน
Morgan Thrapp

ฉันไม่เชี่ยวชาญในงูหลาม แต่all(x in a for x in b)ยังตรวจสอบว่าองค์ประกอบใน b และ a ปรากฏในลำดับเดียวกันหรือเฉพาะถ้าพวกเขาอยู่ที่นี่?
Katenkyo

@ Katenkyo เพียงแค่พวกเขาทั้งหมดอยู่ที่นั่น แต่คำสั่งที่ได้รับการดูแลโดยการหั่นเมื่อเรารับเงิน
Morgan Thrapp

ตกลงเช่นกันจะไม่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 aทำให้คุณประหยัดไบต์ได้ใช่ไหม
Katenkyo

5

Python 3.5, 87 ไบต์

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

repl.it เพื่อตรวจสอบกรณีทดสอบทั้งหมดเพื่อตรวจสอบกรณีทดสอบทั้งหมด

มันทำงานอย่างไร

  • '(.*?)'.join(p) สร้างรูปแบบการค้นหาที่ตรงกับลำดับที่จะถูกแทนที่และสิ่งใดระหว่างองค์ประกอบ

    เนื่องจากตัวนับแต่ละตัวขี้เกียจ (.*?)จะจับคู่ตัวละครให้น้อยที่สุด

    สำหรับรูปแบบghostการ regex g(.*?)h(.*?)o(.*?)s(.*?)tสร้างเป็น

  • '\g<%d>'.join(r)%(*range(1,len(r)),) สร้างสตริงการแทนที่โดยใช้การจัดรูปแบบสตริง

    แต่ละ\g<n>หมายถึงn THกลุ่มจับเช่นเดียว\nหากว่า

    สำหรับการเปลี่ยนสตริงสร้างเป็น123451\g<1>2\g<2>3\g<3>4\g<4>5

  • re.sub(...,...,s,1)sดำเนินการในการเปลี่ยนมากที่สุดคนหนึ่งในสตริง


4

Pyth, 27

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

ชุดทดสอบ

ชุดทดสอบละเว้นสองกรณีสุดท้ายเพราะหน่วยความจำไม่เพียงพอ อัลกอริทึมที่ใช้ในที่นี้คือการค้นหาดัชนีทั้งหมดของอักขระแต่ละตัวในสตริงที่สองในสตริงแรกจากนั้นค้นหาการเรียงลำดับที่เป็นไปได้ทั้งหมดของดัชนีเหล่านั้นและรับเฉพาะดัชนีที่เรียงลำดับเท่านั้น จากนั้นใช้รายการแรกเหล่านี้ตามลำดับที่จัดเรียงเป็นรายการดัชนีในสตริงแรกเพื่ออัปเดตด้วยค่าจากสตริงที่สาม

ฉันรู้สึกว่าควรจะมีบางสิ่งที่สั้นกว่า.nM*F...


4

MATL , 33 ไบต์

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

ลองออนไลน์!

คำอธิบาย

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)

3

JavaScript (ES6), 84 ไบต์

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

คำอธิบาย / ทดสอบ


3

JavaScript (ES6), 84 76 ไบต์

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

เพราะฉันแน่ใจว่านี่เป็นงานของ RegExp

แก้ไข: บันทึกแล้ว 8 ไบต์ขอบคุณ @ MartinBüttner♦

คำตอบ Ruby ของ @ KevinLau มีขนาด 82 ไบต์:

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

ฉันยังลองใช้โซลูชัน RegExp แบบเรียกซ้ำ แต่ใช้ 90 ไบต์:

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

3

จูเลีย89 89ไบต์

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

ใช้ดัชนีiเพื่อทำซ้ำผ่านสตริงรูปแบบ / การแทนที่ในขณะที่เราไป -19 ไบต์ขอบคุณ @Dennis!


2

C, 98 ไบต์

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;}

/ * รหัสขยาย * /

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;
}

อาร์กิวเมนต์คือ: i nput string, o utput buffer, s earch string, r eplacement

หลังจากจดจำการเริ่มต้นของอินพุทและเอาท์พุทเราก็เดินอินพุทแทนที่และก้าวหน้าแทนเมื่อใดก็ตามที่เราตีหนึ่ง ในตอนท้ายถ้าเราหมดการสับเปลี่ยนให้ส่งคืนบัฟเฟอร์เอาต์พุตหรืออินพุตอื่นที่ไม่ได้แก้ไข

/ * การทดสอบ * /

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;
}

2

R, 76 ไบต์

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

การใช้งาน subเพื่อแทนที่คู่แรก

Ungolfed

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

2

C ++, 204 ไบต์

แข็งแรงเล่นกอล์ฟ

#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;}

Ungolfed

#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;
}

ผมไม่คิดว่าคุณกำลังใช้มากพอที่จะรับประกันการใช้std using namespace std;การใช้std::cin, std::coutและstd::stringจะประหยัดได้ 5 ไบต์เนื่องจากสิ่งเหล่านั้นดูเหมือนจะเป็นประโยชน์อย่างเดียวของ namespace นั้น
หมึกมูลค่า

@KevinLau ขอบคุณ! คุณคิดถูกแล้วฉันคิดอย่างนั้น แต่ไม่นับว่าจริง ๆ แล้วมันจะช่วยประหยัดตัวอักษรได้
Michelfrancis Bustillos

Oh! อีกสิ่งหนึ่งเนื่องจากเป็นสิ่งสำคัญ หลังจากที่ได้อ่านมากกว่ารหัสของคุณอีกครั้งผมรู้คุณอย่างตะกละตะกลามเปลี่ยนซ้ายสุดเกิดขึ้นของแต่ละตัวอักษรภายในbในaแต่ตัวอักษรต่อมาต้องเป็นหลังจากที่ก่อนหน้านี้ตัวอักษรเช่นกัน (ดูกรณีทดสอบ 3 และเปรียบเทียบกับผลลัพธ์ของคุณฉันคิดว่าคุณจะพบว่าโค้ดของคุณจะส่งออกabc21ed...เมื่อผลผลิตที่คาดหวังเป็นabcd1e2...!)
Value Ink

ในอินพุตคอมไพเลอร์ ideone C ++ 14 ของ "Adregffftd \ nA23 \ nzac \ n" เหนือโค้ด 10 นาทีที่ผ่านมาสร้างเอาต์พุตของ "zdregffftd" แทนที่จะเป็น "Adregffftd"
RosLuP


2

Haskell, 87 ไบต์

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

ฉันสังเกตเห็นการขาดคำตอบของ Haskell และตัดสินใจที่จะแก้ไข สิ่งนี้จะกำหนดฟังก์ชันที่ประกอบไป!ด้วยคำสั่งอาร์กิวเมนต์รูปแบบการแทนที่สตริง ลองที่นี่

คำอธิบาย

ฟังก์ชั่นเสริม#รับรายการxของคู่ตัวอักษร (รูปแบบและการเปลี่ยน) yและสตริง หากตัวอักษร "รูปแบบ" ในxรูปแบบการเรียงลำดับของyมันจะส่งกลับรายการที่ว่างเปล่าและyกับรูปแบบตัวละครแต่ละตัวแทนที่ด้วยคู่ของมัน (x,y)มิฉะนั้นก็จะส่งกลับทั้งคู่ ฟังก์ชั่น!รหัสไปรษณีย์รูปแบบและสตริงการแทนที่เป็นxนำ#ไปใช้กับxและสตริงที่สามและส่งคืนองค์ประกอบที่สองของผลลัพธ์

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.

หากรูปแบบนั้นเป็นส่วนประกอบของสตริงโค้ดจะทำงานในเวลาO (n)ทำให้เกิดการวนซ้ำแบบครั้งเดียวผ่านสตริงและสร้างการแทนที่แบบโลภมากในกระบวนการ อย่างไรก็ตามถ้ารูปแบบนั้นไม่ได้เป็นแบบต่อเนื่องมันจะทำงานในO (2 n )ในกรณีที่แย่ที่สุด นี่เป็นเพราะในทุกตำแหน่งที่รูปแบบและสตริงมีอักขระที่ตรงกันฟังก์ชันเรียกตัวเองเพื่อตรวจสอบว่ารูปแบบนั้นเป็นจริงหรือไม่พบว่ามันไม่ใช่และเรียกตัวเองเป็นครั้งที่สองเพื่อคำนวณผลลัพธ์จริง


2

JavaScript (ES6), 100 95 ไบต์

(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

นี่คือฟังก์ชัน JavaScript Lambda ที่ถูกต้อง returnขาออกเป็นฟังก์ชั่น ใช้อาร์กิวเมนต์สามข้อ ( a,b,c) เพิ่มที่จุดเริ่มต้นและเรียกเช่นf=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")))


ยินดีต้อนรับสู่ PPCG! โดยทั่วไปฟังก์ชั่นที่ไม่ได้ตั้งชื่อนั้นเป็นที่ยอมรับดังนั้นคุณไม่จำเป็นต้องf=เว้นเสียแต่ว่าฟังก์ชั่นของคุณจะเรียกซ้ำ แต่มันก็ดูไม่เหมือนเดิม
Martin Ender

@ MartinBüttnerขอบคุณ! :) ปรับปรุงคำตอบของฉัน
อาร์จัน

น่าเสียดายที่สิ่งนี้จะล้มเหลวหากaไม่มีรูปแบบ ฉันยังไม่แน่ใจว่าการคืนค่าอาร์เรย์เป็นที่ยอมรับ
Dennis

@Dennis ฉันได้อัปเดตโซลูชันแล้ว ฉันคิดว่าถูกต้องแล้ว ขออภัยสำหรับการตอบกลับล่าช้าและการอัพเดท (ฉันเพิ่งสังเกตเห็นความคิดเห็นของคุณดังนั้นความล่าช้า)
Arjun

@ มาร์ตินเอนเดอร์ในขณะที่ฉันกำลังแก้ไขปัญหาทั้งหมดของฉันฉันพบว่าสิ่งนี้ไม่ถูกต้อง แต่ตอนนี้ฉันได้แก้ไขแล้ว และมันก็สั้นลงห้าไบต์ (ตั้งแต่ฉันออกจากสถานที่เล่นกอล์ฟหลายแห่งไปแล้วไม่มีใครแตะต้องฉันเป็นนักกอล์ฟมือใหม่ในเวลานั้นไม่ใช่ว่าฉันเก่งในตอนนี้ ขออภัยที่โพสต์ผิดวิธี
Arjun


1

ระดับแปดเสียง 97 ไบต์

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;

วนซ้ำเพื่อแทนที่ ค้นหาการปรากฏตัวครั้งแรกของอักขระตัวแรกค้นหาอักขระถัดไปในสตริงที่เหลือทำซ้ำ สิ่งที่น่าสนใจอย่างหนึ่งของเรื่องนี้คือ:

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

เนื่องจาก ideone ยังไม่ยอมรับฟังก์ชั่นที่มีชื่ออื่นนอกเหนือจาก '' ฉันจะปล่อยให้ตัวอย่างรันที่นี่ อินพุตจะแสดงสำหรับกรณีทดสอบสองสามครั้งแรกเท่านั้นเพื่อความกระชับ keyคือเอาต์พุตที่คาดหวังansคือเอาต์พุตของฟังก์ชัน

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

งานที่ได้รับมอบหมายของ Octave เหล่านั้นในสถานที่ที่ไม่คาดคิด ( D(t=...)) ทำให้ฉันงงงวย :-)
Luis Mendo

1
@LuisMendo ฮ่าฮ่า ... มันเกือบจะเหมือน ... สแต็ค! :)
บีกเกอร์

1

Python 3, 123 ไบต์

วิธีที่แตกต่างที่ฉันต้องการแบ่งปันซึ่งสั้นลงไม่กี่ไบต์ ไม่มีกฎเกณฑ์สำหรับไลบรารี่ / regex มาตรฐานใช่มั้ย

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 นี่คือสนามกอล์ฟครั้งแรกของฉัน แจ้งให้เราทราบถึงปัญหา / การปรับปรุงใด ๆ


1

Pyth, 22 ไบต์

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

ตรวจสอบกรณีทดสอบทั้งหมดในPyth คอมไพเลอร์

พื้นหลัง

เราสร้าง regex จากรูปแบบโดยการต่อท้าย$และวาง(.*?) between all characters. This regex will match the subsequence to be replaced and anything between its elements, and anything up to the end of the string.

เนื่องจากควอไลเซอร์นั้นขี้เกียจแต่ละตัว(.*?)จะจับคู่ตัวละครให้น้อยที่สุด

g(.*?)h(.*?)o(.*?)s(.*?)t(.*?)$ผีรูปแบบที่สร้างคือ regex

ถ้ารูปแบบตรงกับอินพุต, builtin r<str><regex>3จะส่งกลับอาร์เรย์ที่มี prematch (ทุกอย่างก่อนที่จะประกอบ), กลุ่มที่ถูกจับทั้งหมด (ทุกสิ่งระหว่างและหลังการเรียงลำดับ), และ postmatch (สตริงว่าง)

หากรูปแบบไม่ตรงกัน builtin จะส่งกลับอาร์เรย์แบบซิงเกิลที่มีอินพุตต้นฉบับ

มันทำงานอย่างไร

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

1

เยลลี่ 23 ไบต์

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

นี่คือสองไบต์ยาวกว่าคำตอบ Jelly อื่น ๆ ของฉันแต่มันเสร็จทันที ลองออนไลน์!

การตรวจสอบ

$ 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

มันทำงานอย่างไร

⁴='-;ç\ñ⁴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.


1

Java 7, 102 bytes

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++];}

Detailed try here

// 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++];
}

1

Julia, 93 90 86 bytes

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

Having to test separately if the match was successful kinda destroys the score. A substitution would require casting to Base.SubstitutionString, which probably isn't worth it...

Test run

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"

1

Julia, 62 59 58 bytes

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

I/O is in form of character arrays.

Verification

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"

1

PHP, 130 109 bytes

I´d still like it shorter; could save 3 bytes (""<) if B was guaranteed to not contain 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;

takes arguments from command line. Run with -r.

Replaces the characters when it finds them;
prints copy if all characters have been replaced; original else.


1

Ruby, 70 64 59 58 bytes

Anonymous function. Walk through the string a to build a new string with letters replaced in accordance to the next character in b and c, then if all characters in b are exhausted at the end, return the newly constructed string, otherwise return the original string.

@histocrat helped save 6 bytes via gsub.

Saved 1 byte thanks to @Cyoce.

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

Try it online!


You can save a byte by replacing -1+i+=1 with ~-i+=1
Cyoce

0

Perl, 80 + 1 = 81 bytes

Run with the -p flag

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

Try it online!

The code procedurally generates a search and replace regex command, which it then executes in the last bit of code.

The string ghost in the first example gets turned into the string g(.*?)h(.*?)o(.*?)s(.*?)t(.*?), which means a g followed by 0 or more characters, followed by an h followed by 0 or more characters, followed by etc. The *? quantifier means that the search should be non-greedy and "gobble" as few characters as possible, instead of the default of matching as much as possible.

The string 12345 then gets turned into 1 .$1.2 .$2.3 .$3.4 .$4.5 .$5, which gets evaluated after the regex is performed. Each of $1,$2,$3,$4,$5 is actually a backreference to a capture group (in parentheses) from the first string.


I suggest this code to save a few bytes : perl -pe 'eval"s/".<>=~s/.\K/(.*?)/gr."/".<>=~s/.\K/"\${".++$i."}"/gre."/"'. Came up with it by myself, but it's quite close to yours, so I won't post it, that would be two very close answers, but feel free to edit yours!
Dada

Just had a go at this because I saw it listed as a "related" question to a recent problem. Best I got was perl -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 bytes

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

A basic reduce, not too happy about all those long first, rest and conj function calls. Hoping to see a better approach.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.