23
\$\begingroup\$

Given a string, reverse it interleavingly. Here's how to do it for abcdefghi and abcdefghij, 0-indexed:

  1. Separate the chars at even indices from the chars at odd indices:
    a c e g i
     b d f h
    a c e g i b d f h j
  2. Reverse the chars at odd indices:
    a c e g i
     h f d b
    a c e g i j h f d b
  3. Interleave into one string again:
    ahcfedgbi
    ajchefgdib

Rules

  • You must support both even-length and odd-length strings.
  • 0-index-wise, you must reverse the chars at odd indices, not even.
  • 1-index-wise, of course, you must reverse the chars at even indices, not odd.
  • Input will consist of printable ASCII (code points 32-126), no newlines.
  • You can take input either as a string or as a list of chars (NOT 1-char strings). E.g. String/char[] or char* are allowed, but String[]/char[][] or char** aren't.

Test cases

Input
Output

Hello, World!
HdlroW ,olle!

Hello World!
H!llooW rlde

ABCDEFGHIJKLMNOPQRSTUVWXYZ
AZCXEVGTIRKPMNOLQJSHUFWDYB

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
 }"{$y&w(u*s,q.o0m2k4i6g8e:c<a>_@]B[DYFWHUJSLQNOPMRKTIVGXEZC\A^?`=b;d9f7h5j3l1n/p-r+t)v'x%z#|!~

P
P

AB
AB

xyz
xyz

For the empty string, return the empty string itself.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Related. \$\endgroup\$ May 27, 2017 at 10:10
  • \$\begingroup\$ I remember this being a type of "secret code" (kind of like Pig Latin) that we learned as kids in 80's or 90's, something to do with the word "fence" or something, but my memory's a bit fuzzy. My friends and I would use this to encode secret messages, and I don't think the adults that found our letters ever did figure them out... \$\endgroup\$
    – phyrfox
    May 28, 2017 at 2:45
  • \$\begingroup\$ @phyrfox you may be thinking of the rail fence cipher, which is similar to this. \$\endgroup\$
    – Carmeister
    May 29, 2017 at 6:32
  • \$\begingroup\$ Ah I remember doing that. \$\endgroup\$
    – 12Me21
    Oct 13, 2017 at 18:03

35 Answers 35

12
\$\begingroup\$

MATL, 8 bytes

t2L)P5M(

Try it online! Or verify all test cases.

Explanation

t     % Implicit input. Duplicate
      % STACK: 'abcdefghi', 'abcdefghi'
2L    % Push [2, 2, 1j]. This represents 2:2:end when used as an index
      % STACK: 'abcdefghi', 'abcdefghi', [2, 2, 1j]
)     % Get entries at those indices
      % STACK: 'abcdefghi', 'bdfh'
P     % Flip
      % STACK: 'abcdefghi', 'hfdb'
5M    % Push [2, 2, 1j] again
      % STACK: 'abcdefghi', 'hfdb', [2, 2, 1j]
(     % Write entries at those indices. Implicit display
      % STACK: 'ahcfedgbi'
\$\endgroup\$
2
  • 5
    \$\begingroup\$ So 2L is "Push [2,2,1j]", and 5M is "Push [2,2,1j] again"... And some people say that golfing languages are not readable! \$\endgroup\$
    – Leo
    May 27, 2017 at 10:29
  • 3
    \$\begingroup\$ @Leo :-D 2L produces a predefined literal. 5M is an automatic clipboard that stores inputs to recent function calls. It could actually be replaced by 2L for the same byte count \$\endgroup\$
    – Luis Mendo
    May 27, 2017 at 10:32
7
\$\begingroup\$

Jelly, 7 bytes

s2ZU2¦Z

This is a full program.

Try it online!

How it works

s2ZU2¦Z  Main link. Argument: s (string)

s2       Split s into pairs.
  Z      Zip/tranpose, grouping characters by the parity of their indices.
     ¦   Sparse application:
   U         Upend; reverse both strings in the pair.
    2        Replace the second string with the reversed string.
      Z  Zip/transpose, interleaving the two strings.
\$\endgroup\$
2
  • \$\begingroup\$ That's exactly my solution byte-by-byte... \$\endgroup\$ May 27, 2017 at 15:31
  • 3
    \$\begingroup\$ Alike minds think great. ;) \$\endgroup\$
    – Dennis
    May 27, 2017 at 15:32
7
\$\begingroup\$

Alice, 10 bytes

/ZY
\IOR@/

Try it online!

Half of the bytes of this program are spent on correctly formatting the source, the actual commands are just IYRZO, because Alice has just the right builtins for this task.

Explanation

As I said, the mirrors (/\), the newline and @ are there just to make the ip move in the right direction and terminate the program at the end. The actual code, linearised, is the following:

IYRZO
I      Input a line
 Y     Unzip it into its even positions and its odd ones
  R    Reverse the odd positions
   Z   Zip it back again
    O  Output

Quite straightforward, I'd say.

\$\endgroup\$
3
  • \$\begingroup\$ If only I could grasp how mirrors work in corners... \$\endgroup\$
    – Luis Mendo
    May 27, 2017 at 10:56
  • \$\begingroup\$ @LuisMendo first you pass through the mirror, which makes you change from cardinal (horizontal/vertical) to ordinal (diagonal) mode or viceversa. Then if you are in cardinal mode you wrap to the other side of the line/column, while if you are in ordinal mode you bounce back against the corner. In this case the south-east mirror is encountered in ordinal mode, makes you switch to cardinal and wrap to the beginning of the second line, where another mirror makes you go back to ordinal and start moving towards north-east \$\endgroup\$
    – Leo
    May 27, 2017 at 11:13
  • \$\begingroup\$ Ah, so the bouncing is only in diagonal, in the same direction you came from. Then it's simpler than I thought. Thanks! \$\endgroup\$
    – Luis Mendo
    May 27, 2017 at 12:58
6
\$\begingroup\$

Java (OpenJDK 8), 108 96 94 93 bytes

Saved 1 byte by using @Neil's neat trick of using s[s.length+~i|1]

String f(char[]s){int a=s.length,b=0;String c="";for(;b<a;b++)c+=s[b%2<1?b:a+~b|1];return c;}

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Java under 100 bytes...seems legit. \$\endgroup\$ May 27, 2017 at 10:53
  • \$\begingroup\$ "Java (OpenJDK 8)" Then why are you using a Java 7 method without recursion? Use a Java 8 lambda by replacing String f(char[]s) with s->.. And you can save a byte as well by putting the int initialization inside the for-loop: for(int a=s.length,b=0;b<a;b++). Try it online. \$\endgroup\$ Aug 31, 2017 at 12:43
5
\$\begingroup\$

Python 2, 52 50 bytes

-2 bytes (and a bug fix) thanks to pxeger

s=bytearray(input())
s[1::2]=s[1::2][::-1]
print s

Try it online! or Try all test cases

\$\endgroup\$
3
  • \$\begingroup\$ 50 Try it online! \$\endgroup\$
    – pxeger
    Feb 19, 2021 at 10:35
  • \$\begingroup\$ You don't seem to have actually updated the code in the post! \$\endgroup\$
    – pxeger
    Feb 24, 2021 at 16:23
  • \$\begingroup\$ @pxeger happens ¯\_(ツ)_/¯ \$\endgroup\$
    – Rod
    May 14, 2021 at 17:29
3
\$\begingroup\$

Octave, 32 bytes

@(a,b=a(x)=a(flip(x=2:2:end)))a;

Try it online!

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

JavaScript (ES6), 48 bytes

f=
s=>s.replace(/./g,(c,i)=>i%2?s[s.length+~i|1]:c)
<input oninput=o.textContent=f(this.value)><pre id=o>

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

Jelly, 9 bytes

Ḋm2U
m2żÇ

Try it online!

Ḋm2U Helper Link -> Dequeue (return last len-1 elements), take every second element, reverse
m2żÇ Main Link -> Take every second element, then interleave with the result of the helper link

-1 byte thanks to Dennis

\$\endgroup\$
2
  • \$\begingroup\$ If you replace ¢ with Ç, you don't need the ³ in the helper link. \$\endgroup\$
    – Dennis
    May 27, 2017 at 15:28
  • \$\begingroup\$ @Dennis Oh what I thought I did that the first time >_> Nevermind, I must have screwed up something. Thanks! \$\endgroup\$
    – hyper-neutrino
    May 27, 2017 at 15:44
3
\$\begingroup\$

Retina, 17 13 bytes

O^$`(?<=\G.).

Try it online!

Fixed an error thanks to Neil.

Saved 4 bytes thanks to Kobi.

Selects each letter preceded by an odd number of characters and reverses them. Does this by using \G which matches the end of the last match.

\$\endgroup\$
5
  • \$\begingroup\$ Last testcase is wrong. You'll need to use $ instead of #. \$\endgroup\$
    – Neil
    May 27, 2017 at 15:59
  • \$\begingroup\$ @Neil Whoops, you're totally right. Fixed! \$\endgroup\$ May 27, 2017 at 16:21
  • \$\begingroup\$ You can use \G instead on the lookbehind, and you can remove the $: O^`(?<=\G.). (12 bytes) \$\endgroup\$
    – Kobi
    May 28, 2017 at 4:55
  • 1
    \$\begingroup\$ @Kobi Thanks for the tips! But unfortunately it only seemed like I could remove the $ since all of the inputs were in sorted lexicographical order. I've added a new test case that your code would fail on. \$\endgroup\$ May 28, 2017 at 14:32
  • \$\begingroup\$ @FryAmTheEggman - Got it, good point. Guess it was just luck. \$\endgroup\$
    – Kobi
    May 28, 2017 at 14:49
2
\$\begingroup\$

PHP>=7.1, 58 Bytes

for(;$i<$l=strlen($a=$argn);$i++)echo$a[$i&1?-$i-$l%2:$i];

Online Version

\$\endgroup\$
1
  • 1
    \$\begingroup\$ perfect. OS says I have to type more, but those 7 chars say it all. \$\endgroup\$
    – Titus
    May 28, 2017 at 2:01
2
\$\begingroup\$

Japt, 14 13 bytes

12 bytes of code, +1 for the -P flag.

Saved 1 byte thanks to @Shaggy

¬ë íU¬Åë w)c

Explanation:

¬ë íU¬Åë w)c
¬                   Split the input into an array of chars
 ë                  Get every other char, starting at index 0
   í                Pair with:
    U¬                Input, split into a char array
      Å               .slice(1)
       ë              Get every other char
         w            Reverse
           c       Flatten
-P                 Join into a string

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Hmm, ë2,1 is rather ugly. I think you can do ó o instead, perhaps... \$\endgroup\$ May 29, 2017 at 1:35
  • \$\begingroup\$ @ETHproductions Yeah, I think Åë works too. \$\endgroup\$
    – Oliver
    May 29, 2017 at 23:19
  • \$\begingroup\$ Oh, nice one :-) \$\endgroup\$ May 29, 2017 at 23:38
2
\$\begingroup\$

APL (Dyalog), 9 bytes

Requires ⎕IO←0 (default on many systems) for proper definition of odd and even.

⌽@{2|⍳≢⍵}

Try it online!

 reverse

@ at the elements filtered by the mask result from applying the

{ anonyomous function

2| the mod-2 of

 the indices of

 the tally (length) of

 the argument

} on the argument

\$\endgroup\$
3
  • \$\begingroup\$ Was v16 even out when this question was posted? \$\endgroup\$
    – Adalynn
    Aug 30, 2017 at 10:54
  • \$\begingroup\$ @Zacharý It was in beta, but it doesn't even matter anymore. \$\endgroup\$
    – Adám
    Aug 30, 2017 at 11:06
  • \$\begingroup\$ Oh, so I suppose your gonna use v17 now? \$\endgroup\$
    – Adalynn
    Aug 30, 2017 at 11:10
2
\$\begingroup\$

05AB1E, 7 bytes

ι and have been added since this challenge was posted, both of them save bytes here.

Sι`R.ιJ

Try it online!

If we were allowed to take a list of string of length 1, ι`R.ι would work for 5 bytes.

S         # split the string into a list of characters
 ι        # uninterleave: push [even indices, odd indices]
  `       # push both values seperately to the stack
   R      # reverse the odd indices
    .ι    # interleave the two lists
      J   # join into a string
\$\endgroup\$
2
\$\begingroup\$

Vyxal, s, 3 bytes

yṘY

Try it Online!

Turns out by making my answer valid I saved a byte. Oh the irony

Explained

yṘY
y      # un-interleave
 Ṙ     # reverse
  Y    # re-interleave
\$\endgroup\$
1
  • \$\begingroup\$ You don't need the flag. \$\endgroup\$
    – emanresu A
    Jun 1, 2021 at 9:25
1
\$\begingroup\$

Röda, 34 bytes

f a{a/=""a[::2]<>reverse(a[1::2])}

Try it online!

Explanation

a/=""                    Convert the argument a into an array of length-1 strings
      <>                 Interleave
a[::2]                   Every even element of a with
        reverse(a[1::2]) Every odd element of a reversed

Here is an alternative solution at the same bytecount

36 34 bytes

{[_/""]|_[::2]<>reverse(_1[1::2])}

This is an anonymous function that takes input as a string from the input stream.

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

Python 2, 67 bytes

lambda s,j=''.join:j(map(j,zip(s[::2]+' ',s[1::2][::-1]+' ')))[:-1]

Try it online!

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

OCaml, 70 bytes

let f s=String.(mapi(fun i c->s.[(length s land-2-i-i)*(i mod 2)+i])s)

Try it online!

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

Haskell, 63 bytes

(_:r)!(a:s)=a:s!r
_!_=[]
f s=([' '|even$length s]++reverse s)!s

Try it online! Usage: f "some string".

For odd strings like abcdefghi, the function f passes the string and its reversal to the function !, which alternates taking chars from both strings. For even strings this does not work, and we need to append a dummy character first to get the offset right.

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

C, 69 bytes

c,l;f(char*s){l=strlen(s);for(c=0;c<l;++c)putchar(s[c&1?l-l%2-c:c]);}

Pretty simple. Walks the string, printing either the current character or the opposite one.

Ungolfed and explained:

f(char *str) {
    int len = strlen(str);      // Get the total length
    for(int c = 0; c<len; ++c)  // Loop over the string
        putchar(s[              // Print the char that is,
            c & 1               // if c is odd,
                ? l - l % 2 - c // c chars from the end (adjusting odd lengths),
                : c             // and at index c otherwise
        ]);
}
\$\endgroup\$
1
\$\begingroup\$

Mathematica, 82 bytes

""<>(f=Flatten)[{#&@@#,Reverse@Last@#}&@f[Characters@#~Partition~UpTo@2,{2}],{2}]&
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 21 bytes

DgÉi¶«}2ô.BøRćR‚˜øJ¶K

Try it online!

I'm guessing the reason this wasn't done in 05AB1E yet is because it's gross...

Yet another time the zip function's auto-drop-last-element hurts instead of helps.

P.S. If you have improvement suggestions on my answer, post your own; it's likely enough of an improvement to warrant you getting the points. I am pretty ashamed of this answer.

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

K (oK), 18 bytes

Solution:

{x[w:&2!!#x]:x@|w}

Try it online!

Examples:

> {x[w:&2!!#x]:x@|w}"Hello, World!"
"HdlroW ,olle!"
> {x[w:&2!!#x]:x@|w}"Hello World!"
"H!llooW rlde"

Explanation:

Interpretted mostly right-to-left, find the odd-indices characters, reverse them and put them back into the string

{x[w:&2!!#x]:x@|w} / solution
{                } / lambda function with implicit parameter x
         #x        / count x,    #"Hello, World!" -> 13
        !          / til,        !13 -> 0 1 2 3 4 5 6 7 8 9 10 11 12
      2!           / 2 modulo,   2!0 1 2 3 4 5 6 7 8 9 10 11 12 -> 0 1 0 1 0 1 0 1 0 1 0 1 0
     &             / where true, @0 1 0 1 0 1 0 1 0 1 0 1 0 -> 1 3 5 7 9 11
   w:              / store in variable w
               |w  / reverse w,  |1 3 5 7 9 11 -> 11 9 7 5 3 1
             x@    / index into x at these indices
 x[        ]:      / assign right to x at these indices
\$\endgroup\$
1
\$\begingroup\$

J, 26 bytes

[:,@,./(0 1$~#)]`(|.@])/.]

ungolfed

[: ,@,./ (0 1 $~ #) ]`(|.@])/. ]

explanation

  • (0 1$~#)]`(|.@])/.] Use Key /. to split the input into the even/odd groups: (0 1$~#) creates the group definition, by repeating 0 and 1 cyclically to the length of the input. We use the gerundial form of Key for its main verb ]`(|.@]), which applies the identity to the first group and reverses the second group: (|.@]).
  • Now that we have the two groups, the odd one reversed, we just zip them together and flatten: ,@,./

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ 21 bytes with (\:2|#\)({~/:)#\<.#\. and 19 bytes with [:,@,./]]|./.~2|#` \$\endgroup\$
    – miles
    Oct 15, 2017 at 23:13
  • \$\begingroup\$ thanks miles. is there a typo in the second one? I'm getting an error \$\endgroup\$
    – Jonah
    Oct 16, 2017 at 0:21
  • \$\begingroup\$ @miles also the first one: i understand how it parses and technically what's happening, but i'm not seeing the overall strategy. can you clarify? \$\endgroup\$
    – Jonah
    Oct 16, 2017 at 0:34
  • \$\begingroup\$ oh yes, it's supposed to be [:,@,./]]`|./.~2|#\, the ticks got parsed out \$\endgroup\$
    – miles
    Oct 16, 2017 at 0:57
  • \$\begingroup\$ 17 bytes with 0,@|:]]`|./.~2|#\ \$\endgroup\$
    – miles
    Oct 16, 2017 at 2:41
1
\$\begingroup\$

Japt, 8 6 bytes

ó oÔrí

Try it

ó oÔrí     :Implicit input of string
ó          :Uninterleave
  o        :Modify last element
   Ô       :  Reverse
    r      :Reduce by
     í     :  Interleaving
\$\endgroup\$
1
\$\begingroup\$

Thunno 2, 3 bytes

^rI

Try it online!

Explanation

     # Implicit input

^    # Uninterleave into two parts and push them separately to the stack
     #   "Hello, World!"  ->  "Hlo ol!", "el,Wrd"
     #   "ABCDEF"         ->  "ACE", "BDF"
     #   "P"              ->  "P", ""

 r   # Reverse the top of stack (second part from before)
     #   "Hello, World!"  ->  "Hlo ol!", "drW,le"
     #   "ABCDEF"         ->  "ACE", "FDB"
     #   "P"              ->  "P", ""

  I  # Interleave the two strings together
     #   "Hello, World!"  ->  "HdlroW ,olle!"
     #   "ABCDEF"         ->  "AFCDBE"
     #   "P"              ->  "P"

     # Implicit output
\$\endgroup\$
0
\$\begingroup\$

Python 3, 93 87 bytes

lambda s:"".join("".join(t)for t in zip(s[::2],reversed(s[1::2])))+("",s[-1])[len(s)%2]
\$\endgroup\$
2
  • \$\begingroup\$ Replace reversed(s[1::2]) with s[1::2][::-1] to save 4 bytes \$\endgroup\$
    – Mr. Xcoder
    May 27, 2017 at 12:25
  • \$\begingroup\$ It comes down to 83 bytes and golfable, in the end: f=lambda s,j="".join:j(j(t)for t in zip(s[::2],s[1::2][::-1]))+("",s[-1])[len(s)%2] \$\endgroup\$
    – Mr. Xcoder
    May 27, 2017 at 12:27
0
\$\begingroup\$

Perl 6,  63 58  55 bytes

{[~] .comb[{flat roundrobin (0,2...^*>=$_),[R,] 1,3...^*>=$_}]}

Test it

{[~] flat roundrobin .comb[{0,2...*},{$_-1-$_%2,*-2...*}]}

Test it

{[~] flat roundrobin .comb[{0,2...*},{[R,] 1,3...^$_}]}

Test it

{  # bare block lambda with implicit parameter 「$_」

  [~]                 # reduce using string concatenation operator

    flat              # make the following a flat list

    roundrobin        # grab one from each of the following 2 lists,
                      # repeat until both are empty

    .comb\            # split the input into graphemes (implicit method call)

    [                 # index into that sequence



      { 0, 2 ... * }, # code block producing every non-negative even number


      {               # code block producing reversed odd numbers
                      # (「$_」 here contains the number of available elements)

        [R,]          # reduce with reversed comma operator
                      # (shorter than 「reverse」)

        1, 3 ...^ $_  # odd numbers stopping before it gets
                      # to the number of input elements
      }


    ]
}

I had to use roundrobin rather than zip, because zip stops as soon as one of the input lists is exhausted.

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

Mathematica, 62 bytes

takes as input a string

(s=Characters@#;Row@Riffle[s[[;; ;;2]],Reverse@s[[2;; ;;2]]])&

Try it online!

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

APL (Dyalog), 24 bytes

Bytes golfed thanks to @Adám

A⊣A[i]←⌽A[i←2×⍳⌊2÷⍨⍴A←⎕]

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Are you going to explain your code? \$\endgroup\$
    – Adám
    May 28, 2017 at 18:55
0
\$\begingroup\$

GNU APL 1.2, 24 bytes

R[X]←⌽R[X←2×⍳⌊.5×⍴R←⍞]◊R

APL works from right to left. ⍴R←⍞ assigns user input to R and then evaluates its length. Halve this by multiplying by .5 and apply floor function. returns all numbers from 1 to the argument.

APL operates on arrays, so the array we just got from doubles each element, giving us just the even indices (1-indexed, so relies on ⎕IO being 1).

When accessing multiple indices of a vector, APL gives the elements at those indices in a vector. R[X←2×⍳⌊.5×⍴R←⍞] gives just the even-indexed elements. reverses the elements. Then, assign the reversed values back to the even indices (assigning these indices to X saves 6 bytes).

is the statement separator. After the reversing is done, evaluate R to print the result.

\$\endgroup\$

Your Answer

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

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