20
\$\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\$
  • 1
    \$\begingroup\$ Related. \$\endgroup\$ – Martin Ender May 27 '17 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 '17 at 2:45
  • \$\begingroup\$ @phyrfox you may be thinking of the rail fence cipher, which is similar to this. \$\endgroup\$ – Carmeister May 29 '17 at 6:32
  • \$\begingroup\$ Ah I remember doing that. \$\endgroup\$ – 12Me21 Oct 13 '17 at 18:03

32 Answers 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\$
  • \$\begingroup\$ That's exactly my solution byte-by-byte... \$\endgroup\$ – Erik the Outgolfer May 27 '17 at 15:31
  • 3
    \$\begingroup\$ Alike minds think great. ;) \$\endgroup\$ – Dennis May 27 '17 at 15:32
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\$
  • 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 '17 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 '17 at 10: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\$
  • \$\begingroup\$ If only I could grasp how mirrors work in corners... \$\endgroup\$ – Luis Mendo May 27 '17 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 '17 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 '17 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\$
  • 1
    \$\begingroup\$ Java under 100 bytes...seems legit. \$\endgroup\$ – Erik the Outgolfer May 27 '17 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\$ – Kevin Cruijssen Aug 31 '17 at 12:43
5
\$\begingroup\$

Python 2, 52 bytes

s=list(input())
s[1::2]=s[1::2][::-1]
print`s`[2::5]

Try it online! or Try all test cases

\$\endgroup\$
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\$
  • \$\begingroup\$ If you replace ¢ with Ç, you don't need the ³ in the helper link. \$\endgroup\$ – Dennis May 27 '17 at 15:28
  • \$\begingroup\$ @Dennis Oh what I thought I did that the first time >_> Nevermind, I must have screwed up something. Thanks! \$\endgroup\$ – HyperNeutrino May 27 '17 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\$
  • \$\begingroup\$ Last testcase is wrong. You'll need to use $ instead of #. \$\endgroup\$ – Neil May 27 '17 at 15:59
  • \$\begingroup\$ @Neil Whoops, you're totally right. Fixed! \$\endgroup\$ – FryAmTheEggman May 27 '17 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 '17 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\$ – FryAmTheEggman May 28 '17 at 14:32
  • \$\begingroup\$ @FryAmTheEggman - Got it, good point. Guess it was just luck. \$\endgroup\$ – Kobi May 28 '17 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
    \$\begingroup\$ perfect. OS says I have to type more, but those 7 chars say it all. \$\endgroup\$ – Titus May 28 '17 at 2:01
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\$
  • \$\begingroup\$ Was v16 even out when this question was posted? \$\endgroup\$ – Zacharý Aug 30 '17 at 10:54
  • \$\begingroup\$ @Zacharý It was in beta, but it doesn't even matter anymore. \$\endgroup\$ – Adám Aug 30 '17 at 11:06
  • \$\begingroup\$ Oh, so I suppose your gonna use v17 now? \$\endgroup\$ – Zacharý Aug 30 '17 at 11:10
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\$

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

Japt, 8 bytes

ó
v íUÌw

Test it

\$\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\$
  • \$\begingroup\$ 21 bytes with (\:2|#\)({~/:)#\<.#\. and 19 bytes with [:,@,./]]|./.~2|#` \$\endgroup\$ – miles Oct 15 '17 at 23:13
  • \$\begingroup\$ thanks miles. is there a typo in the second one? I'm getting an error \$\endgroup\$ – Jonah Oct 16 '17 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 '17 at 0:34
  • \$\begingroup\$ oh yes, it's supposed to be [:,@,./]]`|./.~2|#\, the ticks got parsed out \$\endgroup\$ – miles Oct 16 '17 at 0:57
  • \$\begingroup\$ 17 bytes with 0,@|:]]`|./.~2|#\ \$\endgroup\$ – miles Oct 16 '17 at 2:41
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\$
  • \$\begingroup\$ Replace reversed(s[1::2]) with s[1::2][::-1] to save 4 bytes \$\endgroup\$ – Mr. Xcoder May 27 '17 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 '17 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
    \$\begingroup\$ Are you going to explain your code? \$\endgroup\$ – Adám May 28 '17 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\$
0
\$\begingroup\$

Perl 5, 46 + 3 for -F flag = 49 bytes

while(++$x<@F){print$F[$x%2?$x-1:@F-$x-$#F%2]}

Uses the -F flag to auto split the input into an array of characters, @F. Loops through the array and outputs that element for an even index or that index (plus one for an odd length string) from the end for an odd input.

Takes input with a trailing newline. Without the trailing newline, can just change the pre-increment on $x to a post-increment.

A little more readable:

while(++$x<@F) { #While the index is less than the number of elements in the array. $x is 1-indexing the array despite the fact that perl is 0-indexed because it keeps us from having to use a proper for loop or a do-while loop
    if($x%2) { #If $x is odd
        print $F[$x-1] #Print the element
    } else {
        print $F[@F-$x-$#F%2] #Print from the end. $#F%2 fixes it for odd length strings    
    }
}
\$\endgroup\$
0
\$\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\$
0
\$\begingroup\$

q/kdb+, 70 56 47 38 35 29 27 bytes

Solution:

{x[w]:x(|)w:(&)#:[x]#0 1;x}

Example:

q){x[w]:x(|)w:(&)#:[x]#0 1;x}"Hello, World!"
"HdlroW ,olle!"
q){x[w]:x(|)w:(&)#:[x]#0 1;x}"Hello World!"
"H!llooW rlde"

Explanation:

Find the odd indices of the string, reverse this list, pull out elements at these points and then reassign them in-place to the original string.

{x[w]:x reverse w:where count[x]#0 1;x} / ungolfed
{                                   ; } / lambda function with two lines
                                 0 1    / the list (0;1)
                                #       / take
                        count[x]        / length of input
                  where                 / indices where this is > 0
                w:                      / save in variable w
        reverse                         / reverse this list
      x                                 / index into x at these points
     :                                  / assignment             
 x[w]                                   / assign x at indices with new values
                                     x  / return x

Edits:

  • -9 bytes; switching out count for (#:), til for (!), where for (&:) and reverse for (|:).

  • -3 bytes; switching out (#:) for (#), (&:) for (&) and (|:) for (|)

  • -6 bytes; complete re-write

  • -2 bytes; using assignment rather than apply

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

05AB1E, 12 bytes

RDgÈúøvyNÉè?

Try it online!

RDgÈúøvyNÉè?   Implicit input: "abcdefghij"
R              Reverse the string: "jihgfedcba"
 DgÈú          Put (length is even?1:0) spaces in front of it " jihgfedcba"
     ø         Zip (reinjects the input implicitly): ["a ", "bj", "ci", ...]
      vy       For each element of the list
        NÉè    Extract&push element[iteration is odd?1:0] 
           ?   Print without newline
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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