14
\$\begingroup\$

Given an input string and a wrapping string, find the location of the first input string char in the wrapping string and replace it with the wrapping string char 1 step to the right of that, find the second char in the wrapping string and replace it with the char 2 steps to the right, find the third and replace it with the char 3 steps to the right, and so on. If there are not enough chars in the wrapping string, wrap around.

The wrapping string does not have duplicates and the input string will always be made of chars in the wrapping string.

Reference implementation

s, wrap = input(), input()
n = 1
res = ""
for char in s:
    res += wrap[(wrap.index(char) + n) % len(wrap)]
    n += 1
    
print(res)

Test Cases

abc abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ => bdf

xyz abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ => yAC

ZZZ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ => abc

<empty string> <empty string> => <empty string>

abcdefg abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ => bdfhjln

123 0123456789 => 246

121212 12 => 222222

Scoring

This is code golf, so the shortest answer wins!

\$\endgroup\$
2
  • \$\begingroup\$ May we take inputs and output as vectors of character codepoints? \$\endgroup\$
    – pajonk
    Apr 25, 2022 at 18:48
  • \$\begingroup\$ @pajonk yes, you may \$\endgroup\$
    – Alan Bagel
    Apr 25, 2022 at 18:51

22 Answers 22

5
\$\begingroup\$

J, 14 bytes

[{~#@[|i.+#\@]

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ #\@] is a really clever way to write 1+i.@#@] \$\endgroup\$
    – Adám
    Apr 25, 2022 at 20:21
5
\$\begingroup\$

Pip, 15 bytes

(b(b@?B)+U_MEa)

Takes the two strings as command-line arguments. Attempt This Online!

Explanation

(b(b@?B)+U_MEa)
             a   First command-line arg
           ME    Enumerate and map this function to each index, character pair:
   b               Second command-line arg
    @?B            Find index of character
  (    )+          To that, add
         U_        One plus the index from map-enumerate
(b            )  Use each of the resulting numbers to index into 2nd cmdline arg
                 Autoprint, joined together (implicit)
\$\endgroup\$
5
\$\begingroup\$

Jelly,  7  6 bytes

Thanks to @ovs for suggesting looking at swapping the argument order and hence saving a byte!

J+i@€ị

A dyadic Link that accepts the instruction on the left and the wrapping characters on the right and yields a list of characters.

Try it online!

How?

J+i@€ị - Link: instruction, I; wrapping characters W
J      - range of length of I -> [1,2,3,...,length(I)]
    €  - for each c in I:
   @   -   with swapped arguments - f(W, c):
  i    -    first index of c in W 
 +     - add together -> [index(i1 in W)+1,index(i2 in W)+2,...]
     ị - index into W (modular)
\$\endgroup\$
0
4
\$\begingroup\$

R, 41 40 bytes

\(s,w)rep(w,l<-sum(s|1))[match(s,w)+1:l]

Attempt This Online!

Takes input and outputs as vectors of char codes.

Explanation outline:

  • match finds positions of the elements from s in the wrapping string w.
  • We add a sequence from 1 to the length of s to account for "gradually" in the challenge.
  • We need to index that to w with wrapping: using modular arithmetic or repeating w sufficiently many times - the latter turns out shorter.
\$\endgroup\$
4
\$\begingroup\$

APL (dzaima/APL), 10 bytes

Tacit function taking the wrapping string on the left.

⍳⊃¨⌽⍨ᑈ∘⍳∘≢

Try it online!

⍳∘≢ Indices from 1 to the length of the right argument.
⌽⍨ᑈ For each of those numbers, rotate the wrapping string by that amount. This gives a copy of the wrapping string for each character in the right argument, each rotated one further.

Indices of the right argument in the wrapping argument.
⊃¨ Use each of these indices to pick a char from a rotated copy of the wrapping string.

Would be 12 bytes without dzaima/APL's each-right: ⍳⊃¨{⌽∘⍺¨⍳≢⍵}.

\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 43 bytes

Expects (p)(q), where p is an array of characters and q is a string. Returns an array of characters.

p=>q=>p.map((c,i)=>(q+=q)[q.indexOf(c)-~i])

Try it online!

\$\endgroup\$
3
\$\begingroup\$

05AB1E, 4 bytes

kā+è

I/O as a list of characters. (The wrapped string input can be either a string or list of characters, doesn't really matter.)

Try it online or verify all test cases.

Explanation:

      #  e.g. inputs: ["a","b","j"], "abcdefghij"
k     # Get the indices of the characters of the first implicit input-list in the
      # second implicit input
      #  STACK: [0,1,9]
 ā    # Push a list in the range [1,length] (without popping)
      #  STACK: [0,1,9], [1,2,3]
  +   # Add the values at the same positions in the lists together
      #  STACK: [1,3,12]
   è  # Use that to (modular) index into the second (implicit) input
      #  STACK: ["b","d","c"]
      # (after which the list of characters is output implicitly)
\$\endgroup\$
1
  • \$\begingroup\$ This is the shortest one \$\endgroup\$
    – norway-yv
    Apr 27, 2022 at 9:05
3
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 120 116 bytes

	W =DUPL(INPUT,SIZE(I =INPUT))
N	I POS(P) @Q LEN(1) . X @P	:F(O)
	W X LEN(Q) LEN(1) . R
	O =O R	:(N)
O	OUTPUT =O
END

Try it online!

Takes input as Wrapping String, then Input string, separated by a newline.

Slightly outdated explanation (algorithm is basically the same, though):

	I =INPUT			;* input string
	W =DUPL(INPUT,SIZE(I))		;* wrapping string: duplicated length(I) times
N	I POS(P) LEN(1) . X @P	:F(O)	;* match the next character in I as X (and its position as P), and on failure goto O
	W X LEN(P - 1) LEN(1) . R	;* In W, match X, then P - 1 characters, then 1 character as R
	O =O R	:(N)			;* append R to O and goto N
O	OUTPUT =O			;* print (with a newline)
END
\$\endgroup\$
3
\$\begingroup\$

BQN, 27 23 19 16 bytes

(1+⊐+⊒˜∘⊢)⊏+○≢⥊⊣

Anonymous function; takes the wrapping string as left argument and the input string as right argument.

Try it at BQN online

\$\endgroup\$
3
\$\begingroup\$

Python 3.8 (pre-release), 60 bytes

f=lambda i,w,l=1:i and(w+w)[l+w.find(i[0])]+f(i[1:],w+w,l+1)

Try it online!

Improved recursive solution by @tsh

69 bytes

lambda i,w,o='':([(o:=o+(w:=2*w)[len(o)-~w.find(a)])for a in i],o)[1]

Try it online!

Takes 2 strings as input, outputs a string.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ f=lambda i,w,l=1:i and(w+w)[l+w.find(i[0])]+f(i[1:],w+w,l+1) is 60 bytes \$\endgroup\$
    – tsh
    Apr 27, 2022 at 8:30
  • \$\begingroup\$ @tsh nice catch with the i and, returning an empty string and still working \$\endgroup\$
    – friddo
    Apr 27, 2022 at 12:43
  • \$\begingroup\$ At first I was confused how this handles the 121212 12 case since the wrapping string length is much less than the input and I see no modulo operation. But then I saw that the recursive call is made with double the wrapping string, clever! So the wrapping string length will always be bigger than l. \$\endgroup\$
    – justhalf
    Apr 28, 2022 at 3:46
2
\$\begingroup\$

Perl 5 + -plF, 45 bytes

I feel like this should be easier, so I must be missing a trick somewhere...

@l{@F}=0..@F;$_=<>;s/./$F[($l{$&}+"@+")%@F]/g

Try it online!

Explanation

Creates a lookup hash %l using the keys from the "wrapping string" (implicitly stored in @F via -F) and the values as the numbers from 0 to @F (when a list is used in scalar context, the length of the list is used). Then each char in the input string ($_=<>) is s///ubstituted with the corresponding char at the required index in @F, using the current "end of match" list @+ as a string, modulo the list length.

\$\endgroup\$
2
\$\begingroup\$

TECO, 66 60 52 bytes

-1^XGa:Qb<JQiQbUmS^EUm^[.+QiUk^[Qk-(Z*(Qk/Z))J0A:^Ur^[%i^[>

Note that ^X or ^[ are ASCII control codes, thus each counts at 1 byte. The two string arguments are fetched from Q-register a, b, and result is saved to Q-register r

Explanation

^Ua12^[     ! register a !
^Ub121212^[ ! register b !
-1^X        ! Case sensitive search !
1Un         ! n = 1; i = 0 !
Ga          ! Load register a to buffer !
:Qb<        ! Do len(b) times !
J           ! Jump to zero !
QiQbUm      ! Set b[i] to register m !
S^EUm^[     ! Search to the b[i] in buffer !
.-1Uk       ! Save position to k !
(Qk+Qn)-(Z*((Qk+Qn)/Z))J  ! Locate wrapping !
0A:^Ur^[    ! Append to register r !
%n^[%i^[    ! n++; i++ !
>           ! Od !
:Gr         ! print register r !
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Extended), 16 bytes

Anonymous tacit infix function, taking the wrapping string as left argument and the input string as right argument.

⊣⊇⍨≢⍤⊣|1+⍳⍤≢⍤⊢+⍳

Try it online! (last case also works in current version of the language)

 index of each input string char in the wrapping string

+ add to that:

 the indices
 of the
 length
 of the
 right argument (the input string)

1+ increment

| compute the division remainder when divided by:

 the length
 of the
 left argument (the wrapping string)

 select those elements
 from:

 the left argument (the wrapping string)

\$\endgroup\$
2
\$\begingroup\$

Ruby, 51 bytes

->s,w{k=0;s.chars.map{|c|(w*k+=1)[/#{c}.*/][k]}*''}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Factor, 60 bytes

[ [ 1 + [ tuck index ] dip + rotate first ] with map-index ]

Attempt This Online!

Rotating the wrapping string and taking the first character is quite a bit shorter than modular arithmetic or <circular> indexing.

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 70 bytes

i;f(s,w)char*s,*w;{for(i=1;*s;)*s++=w[(index(w,*s)-w+i++)%strlen(w)];}

Try it online!

Inputs two strings.
Returns the answer in the first input string.

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 10 bytes

⭆θ§η⁺⌕ηι⊕κ

Try it online! Link is to verbose version of code. Explanation:

 θ          Input string
⭆           Map over characters and join
   η        Wrapping string
  §         Cyclically indexed by
     ⌕      Index of
       ι    Current character in
      η     Wrapping string
    ⁺       Plus
         κ  Current index
        ⊕   Incremented
            Implicitly print
\$\endgroup\$
1
\$\begingroup\$

Python, 62 bytes

lambda s,w:[w[(w.index(c)+i+1)%len(w)]for i,c in enumerate(s)]

Attempt This Online!

Outputs as a list of characters

\$\endgroup\$
1
  • 1
    \$\begingroup\$ index can be find for -1 \$\endgroup\$
    – Jitse
    Apr 26, 2022 at 11:31
1
\$\begingroup\$

MATL, 7 bytes

y&mtf+)

Try it online!

Takes input as 'wrapping string' then 'input string', separated by a newline.

	% implicit input w,i
y	% dup from below. Stack: w,i,w
&m	% ismember: find the index of each element of i in w
t	% duplicate.
f	% find: return truthy index. Since all are truthy, this returns 1:length(i)
+)	% add and index modularly into w
	% implicit output
\$\endgroup\$
1
\$\begingroup\$

Ruby, 73 bytes

s,w=gets.split;n=1;s.chars.each{|i|print w[(w.index(i)+n)%w.length];n+=1}

The method used is similar to the reference implementation.

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

BQN, 16 bytesSBCS

⊢⊏˜≠∘⊢|1+⊒˜∘⊣+⊐˜

Run online!

-5 from DLosc.

\$\endgroup\$
0
1
\$\begingroup\$

Vyxal, 7 bytes

vḟ:ż+$i

Try it Online!

Port of Jelly answer.

How?

vḟ:ż+$i
vḟ      # For each element in the (implicit) second input, find its index in the (implicit) first input
  :ż    # Duplicate and push a length range [1, length]
    +   # Add top two things on stack together
     $  # Swap so (implicit) first input is pushed to the stack
      i # Index the list into the string
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.