19
\$\begingroup\$

Given a string, if it is even, break the string into 2 even parts, then reverse the parts to get the "reversencoded" string.

Example:

onomatopoeia -> tamonoaieopo

If the string is not of even length, then do not change the position of the middle character, and reverse the letters before and after the middle character.

Example:

pizza -> ipzaz

discord -> sidcdro

Limitations: The input will not contain any other characters other than AlphaNumeric characters. i.e. No newlines/whitespaces.

General contest, shortest code in each language will be winning. Good luck!

btw: i made up the word reversencoded, i'm fairly sure such a form of "encryption" doesnt exist

\$\endgroup\$
1
  • 1
    \$\begingroup\$ "btw: i made up the word reversencoded, i'm fairly sure such a form of "encryption" doesnt exist" Now it does! \$\endgroup\$ Apr 19, 2021 at 16:18

31 Answers 31

16
\$\begingroup\$

Jelly, 6 bytes

ṚŒHZUZ

Try it online!

Explanation

Consider the string ABCDEFGHI:

ṚŒHZUZ
Ṛ      reverse -> IHGFEDCBA
 ŒH    split into halves -> IHGFE
                            DCBA
   Z   transpose -> ID
                    HC
                    GB
                    FA
                    E
    U  reverse each row -> DI
                           CH
                           BG
                           AF
                           E
     Z transpose -> DCBAE
                    IHGF
       implicitly concatenate -> DCBAEIHGF

I never thought the time would come when I'd outgolf Jonathan Allan in Jelly…

\$\endgroup\$
2
  • 2
    \$\begingroup\$ You know that feeling you get when you miss something that seems incredibly obvious in hindsight? +1 \$\endgroup\$ Apr 18, 2021 at 19:03
  • 1
    \$\begingroup\$ It's interesting that this doesn't translate golfily into J, because J fills the bottom right corner with a space, and the row-reversal then moves the E to the 2nd column. Which this means you need special case code to handle that. So J's "matixes are always square" is a liability here. \$\endgroup\$
    – Jonah
    Apr 19, 2021 at 15:35
11
\$\begingroup\$

Factor, 76 72 65 bytes

[ dup length 2 rem swap halves rot cut [ reverse ] tri@ 3append ]

Try it online!

-7 bytes thanks to @Bubbler!

Explanation:

It's a quotation (anonymous function) that takes a string from the data stack as input and leaves a string on the data stack as output. Assuming "pizza" is on the data stack when this quotation is called...

  • dup Duplicate the object on top of the data stack

    Stack: "pizza" "pizza"

  • length Take the length

    Stack: "pizza" 5

  • 2 Push 2 to the stack

    Stack: "pizza" 5 2

  • rem The remainder of dividing second-from-top by top

    Stack: "pizza" 1

  • swap Swap the top two objects

    Stack: 1 "pizza"

  • halves Cut a sequence in half. If the sequence has an odd number of elements, the extra element will be in the sequence that is on top of the stack. halves returns slices for efficiency.

    Stack: 1 T{ slice f 0 2 "pizza" } T{ slice f 2 5 "pizza" }

  • rot Move the object third from the top to the top

    Stack: T{ slice f 0 2 "pizza" } T{ slice f 2 5 "pizza" } 1

  • cut Take a sequence and an index and split the sequence in two at that index. When given an index at either end of a sequence, an empty string will be one of the outputs. cut will "reify" the slice.

    Stack: T{ slice f 0 2 "pizza" } "z" "za"

  • [ reverse ] Push a quotation for tri@ to use later

    Stack: T{ slice f 0 2 "pizza" } "z" "za" [ reverse ]

  • tri@ Apply a quotation to three objects. In this case, reverse them.

    Stack: "ip" "z" "az"

  • 3append Append three sequences

    Stack: "ipzaz"

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Suggest 3append for swap glue, and 2 rem for odd? 1 0 ? \$\endgroup\$
    – Bubbler
    Apr 18, 2021 at 22:52
  • \$\begingroup\$ @Bubbler Great suggestions. For some reason I thought 3append was missing because 2append doesn't exist. I get my versions mixed up. \$\endgroup\$
    – chunes
    Apr 18, 2021 at 23:12
6
\$\begingroup\$

Retina, 36 bytes

^((.)+?)(.)??((?<-2>.)+)$
$^$1$3$^$4

Try it online! Link includes test cases. Explanation:

^((.)+?)(.)??((?<-2>.)+)$

Match a minimal prefix, an optional centre character, and then a suffix of the same length as the prefix. The prefix and centre are lazy rather than greedy as that's shorter than checking that the group $2 is properly balanced.

$^$1$3$^$4

Reverse the prefix and suffix.

\$\endgroup\$
6
\$\begingroup\$

R, 86 bytes

(or 79 bytes with output as a vector of characters instead of a string)

function(s,n=nchar(s),m=n/2+.5,o=n:1)intToUtf8(utf8ToInt(s)[c(o[o<m],o[o==m],o[o>m])])

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Nice golfing for the specific ranges! \$\endgroup\$
    – pajonk
    Apr 18, 2021 at 19:18
  • 1
    \$\begingroup\$ -3 bytes? Try it online! \$\endgroup\$
    – pajonk
    Apr 19, 2021 at 4:34
  • 1
    \$\begingroup\$ @pajonk - Nice! I think you should post it yourself, though: I thought I'd tried all the combinations of indexing with & without ifs, but never found this one. Well done! \$\endgroup\$ Apr 19, 2021 at 5:37
  • 1
    \$\begingroup\$ @pajonk - ...and your approach can even go down by 2 more bytes: Try it online!... \$\endgroup\$ Apr 19, 2021 at 5:39
  • 1
    \$\begingroup\$ Ok, thanks! I posted it. \$\endgroup\$
    – pajonk
    Apr 19, 2021 at 5:54
6
\$\begingroup\$

Jelly, 9 bytes

LHịJ‘œṖ⁸U

Try it online!

Full program, due to Jelly's smash-printing

How it works

LHịJ‘œṖ⁸U - Main link. Takes a string S on the left
L         - Length of S, L
 H        - L÷2
   J      - Indices of S; [1, 2, 3, ..., L]
  ị       - Index into;
             If L is even, this just returns L÷2
             If L is odd, this returns [(L-1)÷2, [(L+1)÷2]
    ‘     - Increment
       ⁸  - Yield S, to prevent œṖ hooking to U
     œṖ   - Partition S at the indices in the left
        U - Reverse each sublist
            Implicitly "smash" together (["ip", "z", "az"] -> "ipzaz") and print
\$\endgroup\$
4
\$\begingroup\$

J, 25 22 bytes

[:;]<@|./.~#\*@-2%~1+#

Try it online!

the idea

Consider discord. We solve in two steps:

  • Create a mask like _1 _1 _1 0 1 1 1. For even number inputs, the mask will not contain 0.
  • Use that mask to partition into groups, reversing each group.

J details

Using discord as an example:

  • 1+# The length plus one, 8 in this case

  • 2%~ Divided by 2, so now 4.

  • - Subtracted elementwise from

  • #\ The range 1..<length>

     _3 _2 _1 0 1 2 3
    
  • *@ Sign of each:

     _1 _1 _1 0 1 1 1
    
  • /.~ Use that as mask to group the input

  • <@|. Reversing and boxing each group

    ┌───┬─┬───┐
    │sid│c│dro│
    └───┴─┴───┘
    
  • [:; Raze

    sidcdro
    
\$\endgroup\$
4
\$\begingroup\$

Python 3.8 (pre-release), 50 bytes

lambda x:x[(l:=len(x)//2)-1::-1]+x[l:-l]+x[:~l:-1]

Try it online!

-8 bytes thanks to dingledooper

\$\endgroup\$
2
  • \$\begingroup\$ 50 bytes \$\endgroup\$ Apr 18, 2021 at 21:47
  • \$\begingroup\$ @dingledooper oh, that's a nice way to use slices. thanks! \$\endgroup\$
    – hyper-neutrino
    Apr 18, 2021 at 22:06
4
\$\begingroup\$

JavaScript (ES6),  59  58 bytes

Saved 1 byte thanks to @edc65

Expects an array of characters.

s=>s.map(c=>s[i*2]?p=s[i+++i]?c+p:p+c:q=c+q,i=p=q='')&&p+q

Try it online!

Commented

s =>                 // s[] = input string, as an array
  s.map(c =>         // for each character c in s[]:
    s[i * 2] ?       //   if s[i * 2] is defined, this is either the first
                     //   half of the string or the middle character of a
                     //   string of odd length:
      p =            //     update p:
        s[i++ + i] ? //       if s[i * 2 + 1] is defined, this is not the
                     //       middle character:
          c + p      //         prepend c to p
        :            //       else (middle character):
          p + c      //         append c to p
    :                //   else (2nd half of the string):
      q = c + q,     //     prepend c to q
    i = p = q = ''   //   start with p = q = '' and i zero'ish
  )                  // end of map()
  && p + q           // return p + q
\$\endgroup\$
2
  • \$\begingroup\$ Wow! Little improvement: manual management of i : s=>s.map(c=>s[i*2]?p=s[i+++i]?c+p:p+c:q=c+q,i=p=q='')&&p+q \$\endgroup\$
    – edc65
    Apr 19, 2021 at 13:21
  • \$\begingroup\$ @edc65 Thank you! The weird thing is I'm almost certain that I tried exactly that and thought it was just as long. \$\endgroup\$
    – Arnauld
    Apr 19, 2021 at 13:26
4
\$\begingroup\$

R, 81 79 bytes

function(s,n=nchar(s),m=n/2+1)intToUtf8(utf8ToInt(s)[c(m:2-1,m[n>1&n%%2],n:m)])

Try it online!

-2 bytes thanks to @Dominic
-2 bytes thanks to @Giuseppe

Developed independently from @Dominic's answer, but some golfs adapted from there.

Abuses the fact that range operator : and extract operator [ both cast their inputs to int.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ 79 bytes. very nice! \$\endgroup\$
    – Giuseppe
    Apr 19, 2021 at 14:06
  • \$\begingroup\$ @Giuseppe, thanks! I need to remember that golf, it's really useful :) \$\endgroup\$
    – pajonk
    Apr 20, 2021 at 4:53
3
\$\begingroup\$

05AB1E, 16 13 12 bytes

R2ä`?IgÉiÁ}?

Try it online!

R     reverse input
2ä    slice to 2 pieces, i.e. ["azz", "ip"]
`     dump pieces to stack
?     print last piece without newline
I     push input
g     length
É     is odd
iÁ}   if true rotate right by one
?     print without newline
\$\endgroup\$
1
  • \$\begingroup\$ Slightly more interesting way IMO: insert an Á before the I, change the É to an È, and change iÁ} to ._. \$\endgroup\$
    – Makonede
    Apr 19, 2021 at 3:04
3
\$\begingroup\$

Retina 0.8.2, 42 bytes

^|$
¶
+`(.*¶)(.)(.*)(.)(¶.*)
$2$1$3$5$4
¶

Try it online! Link includes test cases. Explanation:

^|$
¶

Wrap the input in a working area of three lines.

(.*¶)(.)(.*)(.)(¶.*)
$2$1$3$5$4

Extract the first and last characters of the input, building them up in reverse in the working area.

+`

Continue extracting characters until there is at most one left.

Join the pieces back together.

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

Jelly, 9 bytes

ŒHṚU2¦FƲ⁺

A monadic Link accepting a list that yields a list.

Try it online!

How?

ŒHṚU2¦FƲ⁺ - Link: list, S
        ⁺ - repeat this twice - i.e. f(f(S)):
       Ʋ  -   last four links as a monad - f(x)
ŒH        -     split (x) into two halves (odd length x gives longer first half)
  Ṛ       -     reverse
    2¦    -     apply to second element:
   U      -       upend (reverses just 2nd element)
      F   -     flatten

Another 9 byter using the same method:

ŒHṪ;UFƲ$⁺
\$\endgroup\$
2
3
\$\begingroup\$

Red, 81 bytes

func[s][rejoin[reverse take/part s(n: length? s)/ 2 take/part s n % 2 reverse s]]

Try it online!

Using parse, 93 bytes

func[s][h:(n: length? s)/ 2 d: n % 2 b:[change copy t h skip(reverse t)]parse s[b d skip b]s]

Try it online!

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

SNOBOL4 (CSNOBOL4), 95 bytes

	M =LEN(SIZE(I =INPUT) / 2)
	I M . L ARB . C M . R RPOS(0)
	OUTPUT =REVERSE(L) C REVERSE(R)
END

Try it online!

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

Pyth, 21 bytes

++_<QK/lQ2*@QK%lQ2_>K

Try it online!

Q        # input
K/lQ2    # Set K to len(Q)/2 (integer division)
_<QK     # Take first K elements and reverse them
*@QK%lQ2 # The element at index K taken len(Q) % 2 times
_>K      # Take last K elements and reverse them
++       # Concatenate them

-2 bytes thanks to hakr14

\$\endgroup\$
1
  • \$\begingroup\$ 21 bytes \$\endgroup\$
    – hakr14
    Apr 18, 2021 at 18:25
3
\$\begingroup\$

V (vim), 54 bytes

YpC<c-r>=strlen('<c-r>"')/2
<esc>DkA <esc>0@"li
<esc>$@"hi
<Esc>:%!rev
gJgJF x

Try it online!

The 'no whitespace' guarantee helped a lot with writing this solution.

Explanation

YpC<c-r>=strlen('<c-r>"')/2
Yp                          copy input to new line
  C                         cut and open insert mode
   <c-r>=strlen('<c-r>"')/2 set the line to half of input length
                            call this k

<esc>DkA <esc>0@"li         
<esc>                       exit insert mode
     D                      delete the number k(and copy)
      k                     move to the input
       A <esc>              insert a space at the end
              0@"l          move right k times from the start
                  i         insert a newline

<esc>$@"hi
     $@"hi                  do the same thing, except from the right

<esc>:%!rev                 reverse all lines

gJgJF x                     
gJgJ                        join the three lines
    F                       navigate to the previous space
      x                     delete it
\$\endgroup\$
3
\$\begingroup\$

Julia, 50 48 bytes

a->a[(d=(l=end)÷2):-1:1]a[d+1:l-d]a[l:-1:l-d+1]

Try it online!

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

Vyxal s, 36 bitsv1, 4.5 bytes

Ṙ½∩R∩

Try it Online!

Porting Jelly is always the best way to do code-golf. Can't believe transpose used to be 2 bytes

Explained

Ṙ½∩R∩
Ṙ         # reversed(input)
 ½        # ↑ split into two halves
  ∩       # transpose ↑
   R      # reverse each row in ↑ (when neither argument is a function, reduce performs vectorised reverse instead)
    ∩     # transpose ↑ and sum using s flag
\$\endgroup\$
0
2
\$\begingroup\$

Charcoal, 15 bytes

⭆⪪θ⊘⊕Lθ⭆⪪ι⊘Lθ⮌λ

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

  θ             Input string
 ⪪              Split into pieces of length
      θ         Input string
     L          Length
    ⊕           Incremented
   ⊘            Halved
⭆               Map over pieces and join
         ι      Current piece
        ⪪       Split into pieces of length
            θ   Input string
           L    Length
          ⊘     Halved
       ⭆        Map over pieces and join
              λ Current piece
             ⮌  Reversed
                Implicitly print
\$\endgroup\$
2
\$\begingroup\$

Python 3.8, 63 62 bytes

lambda s:s[(l:=len(s))//2-1::-1]+s[l//2]*(l&1)+s[:-~l//2-1:-1]

Try it online!

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

05AB1E (legacy), 9 bytes

g;¤Ā‚Ć£íJ

Try it online or verify all test cases.

Explanation:

g          # Get the length of the (implicit) input
 ;         # Halve it
  ¤        # Get the last digit (without popping), which is either 0 or 5
   Ā       # Truthify it, converting the 5 to 1 (0 remains 0)
    ‚      # Pair the two values together
     Ć     # Enclose it; appending the leading halve length as trailing item
      £    # Split the (implicit) input into parts of that size (which truncates the
           # decimals)
       í   # Reverse each part
        J  # Join the parts back together to a string
           # (after which the result is output implicitly)

It uses the legacy version of 05AB1E, because in the new version the ¤ won't work on decimals and would require an explicit cast to string (so 10 bytes instead: g;§¤Ā‚Ć£íJ).

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

Japt, 13 bytes

Splits the input (e.g. "pizza" or "pizzas") into an array based on indexes (e.g. ["pi", "z", "za"] or ["piz", "zas"]), then maps each item through string reverse and joins again.

üÏgUÊ*½-½ÃmÔ¬
ü             // Group input characters by mapped value where
 Ï            // depending on whether the index is smaller, equal or larger than
   UÊ*½-½     // input's length in half minus half,
  g           // the value is -1, 0, or 1.
         Ã    // Then,
          mÔ¬ // map each item through reverse and join to a string.

Try it here.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 11 bytes \$\endgroup\$
    – Shaggy
    Apr 18 at 15:21
1
\$\begingroup\$

Scala, 145 bytes

Golfed version, try it online!

def f(a:String)={val h=a.length/2;val m=(if(a.length%2==1)a.charAt(h).toString else"");a.substring(0,h).reverse+ a.substring(h+m.length).reverse}

Ungolfed version

object A extends App {
  val f:String=>String=input=>{
   val halfLength = input.length / 2
   val middleChar = if (input.length % 2 == 1) input.charAt(halfLength).toString else ""
   val firstHalfReversed = input.substring(0, halfLength).reverse
   val secondHalfReversed = input.substring(halfLength + middleChar.length).reverse
   firstHalfReversed + middleChar + secondHalfReversed
  }
  println(f("pizza"))
  println(f("onomatopoeia"))
}
\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 102 106 bytes

-4 bytes thanks to @ceilingcat !

For each character we calculate the index of the character it should switch place with.

Incidentally this calculation also gives -1 for the middle character of an odd-length String, which is quite useful!

s->{var r="";for(int j,i=0,l=s.length();i<l;r+=s.charAt(j<0?i-1:j))j=l-(i++*2/l*2-1)*~l/2-i;return r;}

Try it online!

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

SAS, 132 bytes

%let n=%eval(%length(&s)/2);data;s="&s";length a b$&n;a=s;b=reverse(s);s=cats(reverse(a),ifc(length(s)/2=&n,"",char(s,&n+1)),b);run;

Assuming you have macrovariable s containing the text:

%let s=abcXdef;

Execute ("ungolfed" for readability):

%let n = %eval(%length(&s)/2);

data;
 s = "&s";
 length a b $ &n;
 a = s;
 b = reverse(s);
 s = cats(reverse(a)
         ,ifc(length(s)/2 = &n, "", char(s, &n+1))
         ,b);
run;

to print out content of created dataset (named automatically data<N>) run:

proc print;
run;
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf! It seems that this answer is taking input from a predefined variable, s, which is not allowed, as that makes your program a snippet. You could, however, make this into a function or take input from STDIN at the start. \$\endgroup\$
    – The Thonnu
    Apr 21 at 19:09
1
\$\begingroup\$

ReRegex, 146 bytes

( *)@(.)/$2$1 @/@$/%/(\w)( *)( +) %\2(?! )/$2$3% $2$1/(.*?)(\w) ( +)%\3(.*)/!$1>$2!$4>/^(\w*?)( +)%\2(.*)/!$1>!$3>/!(\w*?)(\w)>/$2!$1>/!>//@#input

Explained

( *)@(.)/$2$1 @/                    # Count characters. Add a space for every character in the string.
@$/%/                               # Once counting is done, move to dividing
(\w)( *)( +) %\2(?! )/$2$3% $2$1/   # Push character an space pairs over to the other side until it's roughly equal to the lefti n length
(.*?)(\w) ( +)%\3(.*)/!$1>$2!$4>/   # When they're roughly equal, split odd groups into !left>mid!right>
^(\w*?)( +)%\2(.*)/!$1>!$3>/        # Same as above but without the mid character.
!(\w*?)(\w)>/$2!$1>/                # Push the last character of a !> group right behind it, effectively reversing the string.
!>//                                # Clear up any emtpy !> groups
@#input                             # Format the input with a @ counter behind it.

Try it online!

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

Japt, 11 bytes

Ôñ@Ê*½-½ gY

Try it

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

Nibbles, 8 6.5 bytes (13 nibbles)

Saved 1.5 bytes by porting xigoi's Jelly solution like lyxal did

+`'.`'`\~\@\$

Attempt This Online!

Explanation

+`'.`'`\~\@\$
          @    First line of stdin
         \     Reverse
      `\~      Split into two parts
    `'         Transpose
   .           Map this function to each string in that list:
           \$   Reverse it
 `'            Transpose
+              Concatenate together
\$\endgroup\$
0
\$\begingroup\$

Java (JDK), 274 bytes

class A{public static void main(String[]a){System.out.print(new StringBuilder(a[0].substring(0,a[0].length()/2)).reverse().toString()+(a[0].length()%2==1?a[0].charAt(a[0].length()/2):"")+new StringBuilder(a[0].substring((int)(a[0].length()/2D+.5D))).reverse().toString());}}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ @ceilingcat 179 bytes by using interface A{static void main instead of class A{public static void main and StringBuffer instead of StringBuilder. \$\endgroup\$ May 18, 2021 at 14:33
0
\$\begingroup\$

Lua, 69 bytes

s=...n=#s//2print((s:sub(-n)..s:sub(n+1,-n-1)..s:sub(1,n)):reverse())

Try it online!

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