g | x | w | all
Bytes Lang Time Link
034AWK250822T130847Zxrs
017BQN250821T225614Zsterni
006Jelly171227T201657ZJonathan
024Lexurgy220406T004717Zbigyihsu
050Factor220405T213218Zchunes
048PHP4220405T183756Zuser1117
033Curry220405T131741ZWheat Wi
030Julia 1.0210723T122945ZMarcMush
005Vyxal S210715T054736Zemanresu
030Ly210715T095107Zcnamejj
006Japt S171227T222307ZShaggy
00705AB1E171227T201311ZErik the
022K oK171229T110142Zmkst
032JavaScript Node.js171228T093822ZShieru A
033Google Sheets180103T131019ZTaylor R
028APL Dyalog Classic171228T145401ZAdalynn
008QuadR180201T112456ZAdá
035Java 8180201T105951ZKevin Cr
024Alice180103T134235ZMartin E
011J171227T220206ZFrownyFr
117Clojure171231T165204ZCarcigen
065PHP171229T085732ZTitus
053Ruby171229T192817ZHåv
008QuadR171229T024255ZUriel
041R171227T204134Zrturnbul
nansed171228T001827ZNoskcaj
059Clean171227T213751ZΟurous
078Excel VBA171228T190919ZTaylor R
045Haskell171227T194729ZWheat Wi
072Wolfram Language Mathematica171228T122052Zuser2027
117Wolfram Language171227T205948ZEdmund
077Standard ML MLton171227T221521ZLaikoni
054C171227T195939ZSteadybo
041Haskell171228T033719Zxnor
107PHP171227T231516ZZerquix1
100brainfuck171228T024734ZJo King
050Matlab R2016b171227T201439ZThiago O
013Retina171227T232722ZNeil
040Haskell171227T204916ZLaikoni
nanPerl 5171227T204152ZXcali
nanSNOBOL4 CSNOBOL4171227T201240ZGiuseppe
060Prolog SWI171227T202241ZWheat Wi
045Haskell171227T195222Ztotallyh
010Jelly171227T201121Zdylnan
034Funky171227T200425ZATaco
122BrainFlak171227T195944ZDJMcMayh
004V171227T195211Zuser4180
050Python 3171227T194729ZDJMcMayh

AWK, 34 bytes

$0=gensub(/(.)(.)\>/,"\\2\\1","g")

Attempt This Online!

Or, before I figured out the regex trick, at 64 bytes:

{for(;$++i;)printf substr($i,1,l=split($i,a,X)-2)a[l+++2]a[l]FS}

BQN, 17 characters

∾(+`«∘≠⟜' ')⌽¨∘⊔⊢

Try it here!

Explanation

The function consists of a two 2 and a 3-train. If we were to write it out with the argument 𝕩 where necessary and function composition removed, we'd have:

{∾ ⌽¨ (+` « ' '≠𝕩) ⊔ 𝕩}

Below, I've tried to sketch what happens and I use the golfed code again:

                ⊢  # For the left argument of group (⊔) we use the identity
                   # function, i.e. it receives the string argument.
 (    ≠⟜' ')       # For the right argument we start by mapping the string
                   # using the predicate ≠⟜' ', so "The bomb" becomes 1‿1‿1‿0‿1‿1‿1‿1.
    «              # Shift left by 1 which shifts in 0, so we get     1‿1‿0‿1‿1‿1‿1‿0.
  +`               # Scan using + left to right, so we get            1‿2‿2‿3‿4‿5‿6‿6.
                   # By shifting the boolean array to the left, we have
                   # ensured that the position before a space in the original
                   # argument gets the same number as its predecessor in the
                   # scan result!
               ⊔   # Group the original argument into “buckets” designated by the
                   # integer list we just computed for the left argument which
                   # gives us:             ⟨ "", "T", "he", " ", "b", "o", "mb" ⟩
            ⌽¨     # Reverse every string: ⟨ "", "T", "eh", " ", "b", "o", "bm" ⟩
∾                  # Concatenate:          "Teh bobm"


∾(+`«∘≠⟜' ')⌽¨∘⊔⊢  # The entire thing.

Jelly,  7  6 bytes

-1 with the May 2018 introduction of the quick (previously it was only available as the two-byte Ѐ).

Ḳ2œ?ⱮK

A monadic link taking and returning lists of characters

Try it online!

How?

Ḳ2œ?ⱮK - Link: list of characters
Ḳ      - split at spaces
 2     - literal two
    Ɱ  - map with:
  œ?   -   nth permutation (the 2nd permutation has the rightmost elements swapped)
     K - join with spaces

Lexurgy, 24 bytes

This kind of challenge is one of the canonical reasons for captures in Lexurgy to exist (for things like metathesis and reduplication).

Capture 2 of any character, and swap their order when they are at the end of a "word".

a:
[]$1 []$2=>$2 $1/_ $

Factor, 50 bytes

[ " "split [ 2 cut* reverse append ] map " "join ]

Try it online!

Factor's regular expressions don't support backreferences for philosophical reasons, so here's (possibly) the next best thing. It splits the input on spaces, applies a quotation to each word, and joins them with a space into a single string. Here's how the mapping quotation works:

          ! "Flipping"
2 cut*    ! "Flippi" "ng"
reverse   ! "Flippi" "gn"
append    ! "Flippign"

PHP4 (48 chars)

Given $argv[1] as a command line argument :

echo preg_replace('#(.)(.)\b#','$2$1',$argv[1]);

PHP7.4 (48 chars)

The function $f is inverting the last two chars of every word :

$f=fn($s)=>preg_replace('#(.)(.)\b#','$2$1',$s);

Try it Online - Usage :

echo $f('Flippign Lettesr Aroudn');

Both versions are using 🐘's PCRE Text Processing Functions.

Info: Support for PHP4 has been discontinued since 2008 but same code still works in PHP8.1.

Mathematica (58 chars)

f=StringReplace[#,RegularExpression["(.)(.)\\b"]:>"$2$1"]&

Try it online

Curry, 33 bytes

Tested in both KiCS2 and PAKCS.

f(u++[x,y])=u++[y,x]
(>>=f).words

Curry's powerful patterns let it beat the Haskell answer!

To test it you can use Smap. Just select KiCS2 2.2.0 or PAKCS 2.2.0 and paste the following complete code:

f(u++[x,y])=u++[y,x]
g=(>>=f).words
main=f "Hello world an happy day"

Julia 1.0, 30 bytes

!s=replace(s,r"..\b"=>reverse)

Try it online!

detect end of words with a regex r"..\b" and apply reverse on the matches

Vyxal S, 5 bytes

⌈ƛ÷$Ṡ

Try it Online!

-2 thanks to Aaron Miller.

Ly, 30 bytes

i00I[rpr' =[ppf' 0]p0I]pfrp[o]

Try it online!

This one reads all the input into the stack, then copies characters one at a time to the other end of the stack (with a null separator between the original and the "fixed" codepoints). Anytime a space it found, it reverse the position of the previous two codepoints.

When the loop hits the null separator it end, then the just prints the stack.

i00I[rpr' =[ppf' 0]p0I]pfrp[o]
i0                              # Read all the input, then push a null
  0I                            # Copy the bottom of the stack to the top
    [                 ]p        # Loop until the null reaches the bottom of the stack
     rpr                        # Reverse, pop, reverse (delete bottom of the stack)
                    0I          # Copy the bottom of the stack to the top
        ' =                     # Is the codepoint " "?
           [p    0]p            # If-then, runs if codepoint is " "
             pf'                # Delete " ", flip two entries, add " " back
                        f       # End of input, flip the last two codepoints
                         rp     # Reverse stack, delete null
                           [o]  # Print the stack as characters

Japt -S, 7 6 bytes

A port of Jonathan's Jelly solution.

¸Ëá ÅÎ

Try it

¸Ëá ÅÎ     :Implicit input of string
¸          :Split on spaces
 Ë         :Map
  á        :  Permutations
    Å      :  Slice off the first element
     Î     :  Get the first element
           :Implicit output joined with spaces

05AB1E, 7 bytes

#vy`sðJ

Try it online!

-1 thanks to Magic Octopus Urn.

Prints one trailing space.

K (oK), 23 22 bytes

" "/{x@prm[!#x]1}'" "\

Try it online!

Example:

" "/{x@prm[!#x]1}'" "\"Hello World"
"Helol Wordl"

Explanation:

Port of FrownyFrog's solution to save 1 byte.

I'll come back to this.

" "/{prm[x]1}'" "\ / the solution
              " "\ / split input on " "
    {       }'     / apply lambda to each
     prm[x]        / permute input x
           1       / and take the 2nd result
" "/               / join with " "

Previous solution:

JavaScript (Node.js), 38 36 32 bytes

s=>s.replace(/(.)(.)( |$)/g,"$2$1 ") 
s=>s.replace(/(.)(.)\b/g,"$2$1")

Try it online!

RegExp approach courtesy @Giuseppe (although I thought of this independently), assuming words separated by only one space

-2 for only considering 1 space and add trailing space

-4 Thanks @Shaggy

Google Sheets, 33 Bytes

Anonymous worksheet function that takes input from cell A1 and outputs to the calling cell

=RegExReplace(A1,"(.)(.)\b","$2$1

-2 Bytes Thanks to @KevinCruijssen for the use of (.) over (\w)

APL (Dyalog Classic), 28 bytes

1↓∊((¯2↓⊢),2↑⌽)¨' '(,⊂⍨⊣=,)⍞

⎕ML and ⎕IO are both 1,

Try it online!

Explanation

QuadR, 8 bytes

..\b
⌽⍵M

Try it online!

..\b any two characters followed by a word boundary

gets replaced with

⌽⍵M the reverse of the Match


Equivalent to the following 18-byte Dyalog APL function:

'..\b'⎕R{⌽⍵.Match}

Java 8, 35 bytes

s->s.replaceAll("(.)(.)\\b","$2$1")

Port of @TaylorScott's Google Sheets answer, after I golfed two bytes. EDIT: I see it's now a port of Neil's Retina answer after my two golfed bytes.

Explanation:

Try it online.

s->                           // Method with String as both parameter and return-type
   s.replaceAll("(.)(.)       //  Replace any two characters,
                       \\b",  //  with a word-boundary after it (space or end of String)
                "$2$1")       //  With the two characters swapped

Alice, 24 bytes

/0RR'.%$1\' o
\ix*o ne@/

Try it online!

Explanation

/...\' o
\.../

This forms a loop where the loop body is a linear Ordinal snippet and we execute ' o in Cardinal mode between every two loop iterations. The latter just prints a space.

Unfolding the zigzag structure of the Ordinal code, the linear loop body actually looks like this:

iR*' %e10xRo.n$@

Breaking this down:

i     Read all input. On subsequent iterations, this will push an empty string.
R     Reverse.
*     Join. On the first iteration, this joins the input to an implicit empty string,
      which does nothing. On subsequent iterations, it will join the empty string to
      the word on top of the string, thereby getting rid of the empty string.
' %   Split around spaces. On the first iteration, this will split the input
      into individual words. On subsequent iterations, this does nothing.
e10   Push "10".
x     Use this to permute the (reversed) word on top of the stack. In
      particular, the word is rearranged with the same permutation that is
      required to sort the string "10", which means the first two letters
      get swapped (which correspond to the last two letters of the actual
      word).
R     Reverse the swapped word.
o     Print it.
.n$@  If there are no words left on the stack, terminate the program.

J, 20 19 11 bytes

Credit to @Bolce Bussiere

1&A.&.>&.;:

Try it online!

       &.;:      on words
    &.>          on each
  A.             apply the permutation
1&               number 1, swap the last two elements

Clojure, 122 117 bytes

-5 bytes by shortcutting the indices of the characters to swap

(fn[p](map #(let[l(count %)v(vec %)y(dec l)z(- l 2)](apply str(assoc v y(v z)z(v y))))(clojure.string/split p #" ")))

It's a shame that most of Clojure's String function are tucked away inside of Clojure.string, and that there are no good ways of manipulating the characters of Strings directly. clojure.string/split is atrociously long, and the conversion to-and-from vectors added quite a lot. I might be able to shave off a couple bytes by shortcutting the trailing indices, but this is the only decent algorithm I could think of.

(defn flip-last [phrase]
  (let [words (clojure.string/split phrase #" ")]

    ; For each word...
    (map #(let [len (count %)
                ; Need to turn the string into a vector so we can manipulate it using indices
                vec-word (vec %)]

            ; ... then turn the vector of characters back into a String.
            (apply str
               ; Associate the element at the second last index with the element at the last index,
               ;  and vice-versa...
              (assoc vec-word (dec len) (vec-word (- len 2))
                              (- len 2) (vec-word (dec len)))))

         words)))

PHP, 65 bytes

requires PHP 7.1 (or later)

for(;$s=$argv[++$i];$s[-1]=$s[-2],$s[-2]=$c,print"$s ")$c=$s[-1];

takes sentence as separate command line arguments. Run with -nr.


working on a single string, 77+1 bytes:

foreach(explode(" ",$argn)as$s){$c=$s[-1];$s[-1]=$s[-2];$s[-2]=$c;echo"$s ";}

Run as pipe with -nR.


... or try them online.

Ruby, 53 bytes

$*.each{|x|print x[0,x.length-2]+x[-2,2].reverse," "}

The program takes input through command line arguments (formatted as a regular sentence, without quotes).

$* is a shorthand for ARGV, therefore i can iterate over each of the words, already in an array.

Only thing that bugs me is that awful x.length-2 snippet. I would prefer to use x.last(-2), but i believe that is only in RoR.

Called like:

ruby file.rb Helol Wordl

So that each word becomes a parameter. (Not wrapped in quotes)

QuadR, 8 bytes

..\b
⌽⍵M

Try it online!

R, 111 51 41 bytes

Courtesy of @Giuseppe, a regex approach which blows my old method out of the water.

cat(gsub("(.)(.)\\b",'\\2\\1',scan(,"")))

sed, 20 17+1 (-r) = 18 bytes

s/(.)(.)\b/\2\1/g

Try it online!

Clean, 75 59 bytes

-16 from Laikoni

@[a,b]=[b,a]
@[a,b,' ':c]=[b,a,' ': @c]
@[a:b]=[a: @b]
@e=e

Try it online!

Excel VBA, 78 Bytes

Anonymous VBE immediate window that takes input from range A1 and outputs to the VBE immediate window.

For Each s in Split([A1]):l=Len(s):?Left(s,l-2)Right(s,1)Mid(s,l-1,1)" ";:Next

Haskell, 53 45 bytes

u[a,b]=[b,a]
u(a:b)=a:u b
unwords.map u.words

Try it online!

Explanation

u is a function that swaps the last two letters of a word. To apply it to all the words we use words to split the list, map it across all of the words and then use unwords to put it back together.

Wolfram Language (Mathematica), 72 bytes

x""<>(Characters[StringSplit@x][[;;,#]]&/@{;;-3,-1,-2})~Riffle~" "

Try it online!

Another approach using manipulation of character list and take parts instead of string regex.

The two Unicode characters are \[Function] and \[Transpose] in private use area of Mathematica, take 3 bytes each.

74 bytes

Try it online!

Wolfram Language, 117 bytes

StringReplace[RegularExpression["\\b[[:alpha:]]{2,}\\b"]:>StringDrop[StringInsert["$0",StringTake["$0",{-1}],-3],-1]]

Try it online!

Applied to the test strings.

StringReplace[
  RegularExpression["\\b[[:alpha:]]{2,}\\b"] :> 
   StringDrop[StringInsert["$0", StringTake["$0", {-1}], -3], -1]] /@
 {"Thansk", "Youer welcoem", "This is an apple", 
  "Flippign Lettesr Aroudn", "tHe oDd chALlEneg wiht swappde lettesR"} // Column
Thanks
Youre welcome
Thsi si na appel
Flipping Letters Around
teH odD chALlEnge with swapped letteRs

Standard ML (MLton), 92 77 bytes

implode o foldr(fn(a,b:: #" "::r)=>b::a:: #" "::r|(a,r)=>a::r)[#" "]o explode

Try it online! Based on xnor's Haskell solution.


Previous 92 byte version

fun f(a::b:: #" "::r)=b::a:: #" "::f r|f(x::r)=x::f r|f r=r
fun$s=implode(f(explode(s^" ")))

Try it online! Example usage: $ "Flippign Lettesr Aroudn" yields "Flipping Letters Around ".

Ungolfed

fun f (a :: b :: #" " :: r) = b :: a :: #" " :: f r
  | f              (x :: r) = x :: f r
  | f                    r  = r

fun g s = implode (f (explode (s ^ " ")))

Try it online!

C,  62   58  54 bytes

Thanks to @Dennis for saving  four  eight bytes!

f(char*s){s[1]>32||(*s^=s[-1]^=*s^=s[-1]);*++s&&f(s);}

Try it online!

Haskell, 41 bytes

foldr(%)" "
a%(b:' ':r)=b:a:' ':r
a%s=a:s

Try it online!

Outputs with a trailing space.

The repeated ' ':r looks wasteful. But a%(b:t@(' ':r))=b:a:t is the same length and a%(b:t)|' ':_<-t=b:a:t is one byte longer.


Haskell, 41 bytes

f(a:b:t)|t<"A"=b:a:f t|1>0=a:f(b:t)
f e=e

Try it online!

PHP, 119 107 bytes

Edit: thanks to totallyhuman

<?php foreach(explode(" ",trim(fgets(STDIN)))as$w)echo substr($w,0,strlen($w)-2).strrev(substr($w,-2))," ";

Try it online!

brainfuck, 109 100 bytes

Edit: don’t have to handle one letter words

,[>++++[-<-------->],]>+[-<[>++++[<++++++++>-]<[->>+<<]<]<<[->>+<<]>[[-<+>]>]<<[>+>+>]-<]>>>>>>>[.>]

Try it online!

Prints a trailing space

How It Works

,[>++++[-<-------->],] Puts input on the tape and subtracts 32 from each character
                       This separates each word

>+[- Start the loop
   <[>++++[<++++++++>-]<[->>+<<]<] Add 32 to each letter of the word
                                   Skip this on the first iteration for the last word

   <<[->>+<<]>[[-<+>]>] Swaps the last two letters of the word
   <<[>+>+>]- If there is another word to the left continue loop
              Also set up to add a space to the end of the word
 <] End loop
 >>>>>>>[.>] Print the modified string

Previous version, 109 bytes

,[>++++[-<-------->],]>+[-<[>++++[<++++++++>-]<[->>+<<]<]<<[[->>+<<]>[[-<+>]>]<<[<]]>[>]<[>+>+>]-<]>>>>>>[.>]

Try it online!

Matlab (R2016b), 51 50 bytes

Saved 49 50 (!) bytes thanks to @Giuseppe.

function s(a),regexprep(a,'(\w)(\w)( |$)','$2$1 ')

And my previous answer:

Matlab (R2016b), 100 bytes

(Just for the fun of it :P)

function s(a),a=regexp(a,' ','split');for i=1:length(a),fprintf('%s ',a{i}([1:end-2 end end-1])),end

Explanation:

function s(a) % Defining as a function...
a=regexp(a,' ','split'); % Splits the input string at the spaces
for i=1:length(a) % Loops through each word
    fprintf('%s ',a{i}([1:end-2 end end-1])) % And prints everything with the last two characters swapped.
end

Retina, 13 bytes

(.)(.)\b
$2$1

Try it online! Link includes test cases.

Haskell, 40 bytes

(f=<<).words
f[a,b]=b:a:" "
f(x:r)=x:f r

Try it online! Usage example: (f=<<).words $ "abc xyz" yields "acb xzy ".

Perl 5, 19 + 1 (-p) = 20 bytes

s/(\w)(\w)\b/$2$1/g

Try it online!

SNOBOL4 (CSNOBOL4), 136 119 bytes

	I =INPUT
B	I SPAN(&LCASE &UCASE) . Y ARBNO(' ') =:F(O)
	Y RPOS(2) REM . Z =REVERSE(Z)
	O =O Y ' '	:(B)
O	OUTPUT =O
END

Try it online!

Prints with a trailing space. You know you've done something wrong when a language is a backronym for StriNg Oriented and symBOlic Language and your code is longer than Brain-Flak :( now it's slightly better.

Line B takes I and replaces (alphabetic characters saved as Y)(some number of spaces) with the empty string.

The following line extracts the last 2 characters of Y as Z and replaces them as Z reversed, then the next line concatenates O, Y, and a single space character.

Finally, it prints when I no longer matches the required pattern in line B.

Prolog (SWI), 60 bytes

[A,B]+[B,A].
[A,B,32|U]+[B,A,32|Y]:-U+Y,!.
[A|U]+[A|Y]:-U+Y.

Try it online!

Explanation

First we define the base case:

p([A,B],[B,A]).

This means that the last two letters will always be swapped.

Then we define what happens if we are right next to a space:

p([A,B,32|U],[B,A,32|Y]):-p(U,Y),!.

Two strings match if right before a space the letters before the space are swapped and the remainder if the strings match. We then use ! to cut.

Our last case is if we are not next to a space the first two letters need to match.

p([A|U],[A|Y]):-p(U,Y).

Haskell, 45 bytes

-2 bytes thanks to H.PWiz.

(r.g.r=<<).words
g(x:y:z)=' ':y:x:z
r=reverse

Try it online!

Jelly, 10 bytes

ḲṪ,¥\€Ḋ€UK

Try it online!

Funky, 34 bytes

s=>s::gsub("(.)(.)( |$)","$2$1$3")

Try it online!

Brain-Flak, 122 bytes

{(({})[((((()()){}){}){}){}])((){[()](<{}>)}{}){{}<>(({}({}))[({}[{}])])(<>)}{}({}<>)<>}<>(({}({}))[({}[{}])]){({}<>)<>}<>

Try it online!

The worst language for the job :)

Readable Slightly more readable version:

{
    (({})[((((()()){}){}){}){}])((){[()](<{}>)}{})

    {
        {}
        <>

        (({}({}))[({}[{}])])

        (<>)
    }
    {}

    ({}<>)<>

}<>

(({}({}))[({}[{}])])

{

    ({}<>)
    <>
}<>

V, 4 5 bytes

òeXp

Try it online!

|| denotes the cursor

The buffer starts with |w|ord and more words and the cursor being on the first character.

Recursively ò

go to the end of a word

wor|d| and more words

remove X the character to the left of the cursor

wo|d| and more words

paste it over the next character

wod|r| and more words

Implicit ending ò, repeat the same process for other words until the end of the buffer is reached

Python 3, 50 bytes

print(*(w[:-2]+w[:-3:-1]for w in input().split()))

Try it online!

This answer abuses Python 3's behavior of print: Multiple arguments are printed with a single space between them. Of course, we can't just give it multiple arguments because we don't know how many words will be in the input. So we use the splat operator. Basically

print(*[a,b,c])

is exactly the same thing as

print(a,b,c)

Abusing that makes a full program turn out shorter than a function/lambda where we'd have to use ' '.join or something similar.