g | x | w | all
Bytes Lang Time Link
057Haskell250318T224414ZDLosc
013Pip250318T203725ZDLosc
6513Nibbles230519T041449ZDLosc
045Vyxal s210419T033123Zlyxal
011Japt230518T212031ZShaggy
146ReRegex230501T000401ZATaco
099C gcc230420T201753Zevanstar
132SAS230421T174249ZBartosz
102Java JDK230419T145355ZFhuvi
069Lua230418T215919Zbluswimm
145Scala230418T060709Z138 Aspe
00905AB1E legacy210518T142809ZKevin Cr
274Java JDK210514T150631ZDMiddend
048Julia210419T141007ZMarcMush
079R210419T055227Zpajonk
013Japt210419T204418ZEtheryte
058JavaScript ES6210418T155420ZArnauld
054V vim210419T031228ZRazetime
065Factor210418T172516Zchunes
021Pyth210418T141448ZManish K
050Python 3.8 prerelease210418T154443Zhyperneu
095SNOBOL4 CSNOBOL4210418T191421ZGiuseppe
006Jelly210418T185741Zxigoi
081Red210418T183007ZGalen Iv
009Jelly210418T175505ZJonathan
2522J210418T164016ZJonah
062Python 3.8210418T154502ZNoodle9
042Retina 0.8.2210418T154300ZNeil
009Jelly210418T140152Zcaird co
015Charcoal210418T152556ZNeil
086R210418T151757ZDominic
036Retina210418T151529ZNeil
01205AB1E210418T141924ZCommand

Haskell, 57 bytes

g.g
h=(`div`2).length
g s=reverse(drop(h s)s)++take(h s)s

The first line is the solution, an anonymous function. Attempt This Online!

Explanation

Adapted from Jonathan Allan's Jelly answer:

h takes the length of a string and divides it by 2, rounding down.

g takes a string s and splits it at index h s. It reverses the last half (which includes the middle character, if any) and joins that to the first half. This is equivalent to reversing the first half in place and then reversing the whole string.

Our final solution, then, is simply g.g, which applies g twice.

Pip, 13 bytes

ZD J*ZD R*CHa

Attempt This Online!

Explanation

Another port of xigoi's Jelly solution:

ZD J*ZD R*CHa
            a  ; Command-line argument             "discord"
          CH   ; Chop into two halves              ["dis";"cord"]
        R*     ; Reverse each half                 ["sid";"droc"]
     ZD        ; Transpose with default value      [["s";"d"];["i";"r"];["d";"o"];["";"c"]]
   J*          ; Join each                         ["sd";"ir";"do";"c"]
ZD             ; Transpose with default again      [["s";"i";"d";"c"];["d";"r";"o";""]]
               ; Join together; output (implicit)  "sidcdro"

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

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

Japt, 11 bytes

Ôñ@Ê*½-½ gY

Try it

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!

C (gcc), 106 105 99 bytes

First for loop iterates over each half, and the second for loop does the reversing.

-7 bytes thanks to ceilingcat for a bit inversion hack and for optimizing out an unnecessary variable

#define S s[i]^=s[L/2+~i]
i,o,L;f(char*s){L=strlen(s);for(o=0;o<L;s+=o+=L-L/2)for(i=L/4;i--;)S^=S;}

Try it online!

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;

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!

Lua, 69 bytes

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

Try it online!

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"))
}

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

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!

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!

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.

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.

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

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

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

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

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

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!

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…

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!

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Ʋ$⁺

J, 25 22 bytes

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

Try it online!

the idea

Consider discord. We solve in two steps:

J details

Using discord as an example:

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!

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.

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

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

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!

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.

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