# pwaS eht tirsf dna tasl setterl fo hace dorw

Or, "Swap the first and last letters of each word"

Your challenge is to, given a string of alphabetical ASCII characters as well as one other character to use as a delimiter (to separate each word), swap the first and last letters of each word. If there is a one-character word, leave it alone.

The examples/testcases use the lowercase letters and the space as the delimiter.

You do not need to handle punctuation; all of the inputs will only consist of the letters a through z, separated by a delimiter, all of a uniform case.

For example, with the string "hello world":

Input string: "hello world"
Identify each word: "[hello] [world]"
Identify the first and last letters of each word: "[[h]ell[o]] [[w]orl[d]]"
Swap the first letters of each word: "[[o]ell[h]] [[d]orl[w]]"
Final string: "oellh dorlw"


NOTE: the delimiter does not need to be inputted separately. The delimiter is just the character used to separate words. It can be anything. I wanted to leave options open for creative golfers, so I did not want to limit it to just spaces or new lines. The delimiter is just a character that separates words in the input string.

Test cases:

"swap the first and last letters of each word" -> "pwas eht tirsf dna tasl setterl fo hace dorw"
"hello world" -> "oellh dorlw"
"test cases" -> "test sasec"
"programming puzzles and code golf" -> "grogramminp suzzlep dna eodc folg"
"yay racecar" -> "yay racecar"

• How should punctuation be treated? Hello, world! becomes ,elloH !orldw (swapping punctuation as a letter) or oellH, dorlw! (keeping punctuation in place)? – Phelype Oleinik May 16 at 19:23
• @PhelypeOleinik You do not need to handle punctuation; all of the inputs will only consist of the letters a through z, and all a uniform case. – Comrade SparklePony May 16 at 19:24
• Second paragraph reads as well as one other character to use as a delimiter while the fourth reads separated by spaces. Which one is it? – Adám May 16 at 19:46
• @Adám Any non-alphabetic character. I’ll edit to clarify. – Comrade SparklePony May 16 at 21:36
• @BenjaminUrquhart Yes. You can take input as a function argument if you want as well. – Comrade SparklePony May 16 at 21:44

# SNOBOL4 (CSNOBOL4), 90 bytes

I	R =
INPUT LEN(1) . L REM . M	:F(END)
M ARB . M RPOS(1) REM . R
OUTPUT =R M L	:(I)
END


Try it online!

Takes input separated by newlines; can be either uppercase or lowercase.

I R =					;* set R to empty string
INPUT LEN(1) . L REM . M	:F(END)	;* take first character and set to L, and set the
;* REMainder to M
M ARB . M RPOS(1) REM . R		;* match an ARBitrary (possibly empty) run
;* of characters to M up to but excluding the last character
;* and save the last character to R
;* if M is empty, (i.e., a one-letter word), then this fails
;* and nothing happens, so M remains empty and R remains empty
OUTPUT =R M L	:(I)			;* output Right, Middle, Left, then goto I.
END


(previous version)

# SNOBOL4 (CSNOBOL4), 92 bytes

I	R =M =
INPUT LEN(1) . L ('' | ARB . M LEN(1) . R) RPOS(0)	:F(END)
OUTPUT =R M L	:(I)
END


Try it online!

This is thematically the same, clearly, but suffers from using FAILURE as the termination status, preventing us from using FAILURE as a no-op as we do in the above. This then forces us to set M = as well as R =, which is 3 bytes.

# PowerShell, 50 bytes

-split"$args"|%{$_-replace'^(.)(.*)(.)$','$3$2$1'}


Try it online!

Uses regex to replace each word with a captured first and last letter surrounding the original core. If it's a single character, replace will find nothing and leave it alone.

# Python 2, 67666461 60 bytes

lambda s:' '.join(w[1:][-1:]+w[1:-1]+w[0]for w in s.split())


Try it online!

-1 byte, thanks to squid

-1 byte, thanks to Erik the Outgolfer

# Python 3, 636158 57 bytes

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


Try it online!

• You can remove the whitespace before ">" – squid May 16 at 19:40
• @squid thanks. I'm on mobile, so whitespace is hard on tio. – TFeld May 16 at 19:43
• Your 58-byte version is now an exact (except for the variable name) copy of alexz02's latest edit from 20 minutes ago – Kevin Cruijssen May 16 at 20:15
• True. I was mentioning it merely as a FYI. :) There isn't any rule disqualifying duplicated answers when both users independently came to the same solutions. – Kevin Cruijssen May 16 at 20:32
• The way you've chosen to account for 1-letter words might prevent you from seeing that this also works, since getting there involves two steps: 1) replace w[:w>w[0]] with w[:-1][:1]; this works because it firstly removes the last character, and, if the word only has one letter, the last character is also the first 2) you then move the mechanism to the other side, so that you have a [0] instead of a [-1]. – Erik the Outgolfer May 17 at 21:29

# PHP, 73 bytes

foreach(explode(' ',$argn)as$w){[$w[0],$w[-1]]=[$w[-1],$w[0]];echo"$w ";}  Try it online! Using PHP 7.1's Square bracket syntax for array destructuring to swap values. Ungolfed: foreach( explode( ' ',$argn ) as $w ) { [$w[0], $w[-1] ] = [$w[-1], $w[0] ]; echo$w, ' ';
}


# Jelly, 9 bytes

ḲṪ;ṙ1$Ɗ€K  Try it online! ### Explanation ḲṪ;ṙ1$Ɗ€K | monadic link taking the string as input

Ḳ         | split at spaces
Ɗ€  | for each word, do the following:
Ṫ        | - pop the last letter
;ṙ1$| - concatenate to the remaining letters rotated left once K | finally, join with spaces  # Z80Golf, 43 bytes 00000000: 2100 c0cd 0380 3822 5745 cd03 8038 09fe !.....8"WE...8.. 00000010: 2028 0570 4723 18f2 736b 707e 23a7 2803 (.pG#..skp~#.(. 00000020: ff18 f87a ff3e 20ff 18d6 76 ...z.> ...v  Try it online! Corresponding assembly: mainloop: ld hl,$c000
call $8003 jr c, hlt ld d, a ld b, l ; handle 1-character words inputloop: call$8003
jr c, endinput
cp $20 jr z, endinput ld (hl), b ; don't store the last character ld b, a inc hl jr inputloop endinput: ld (hl), e ; always 0 ld l, e ld (hl), b outputloop: ld a, (hl) inc hl and a jr z, endoutput rst$38
jr outputloop
endoutput:
ld a, d
rst $38 ld a,$20
rst \$38
jr mainloop
hlt:
halt


# Rust, 110 bytes

|a:&str|{for b in a.split(' '){let l=b.len()-1;if l>0{print!("{}{}",&b[l..],&b[1..l])}print!("{} ",&b[0..1])}}


Try it online!

### A surprisingly long, but nicer solution that returns instead of printing (126 bytes):

|a:&str|->String{a.split(' ').flat_map(|b|{let mut q:Vec<_>=b.chars().collect();q.swap(0,b.len()-1);q.push(' ');q}).collect()}


Try it online!

## C (gcc), 62 bytes

t;*s;f(int*i){for(s=i;*++i;i[1]>64||(t=*i,*i=*s,*s=t,s=i+2));}


I wanted to use a xor swap but that fails if a word is only one character long.

Try it online

• Suggest i[1]<65?t=*i,*i=*s,*s=t,s=i+2:0 instead of i[1]>64||(t=*i,*i=*s,*s=t,s=i+2) – ceilingcat Sep 13 at 17:38

## Brainf**k, 126

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


Try it online!

Could definitely be golfed further.

# Julia 1.0, 75 bytes

x->join([(n=length(s);n<2 ? s : s[n]*s[2:n-1]*s[1]) for s in split(x)]," ")


Try it online!

# brainfuck, 71 67 49 47 bytes

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


Try it online!

This code uses a few cheats, so i don't know if it is competing. The separator in the input is a 0x01. The input needs an extra trailing separator, otherwise the last word won't be printed.

code:

+[                  enter the loop / the first round only the last three commands of the main loop are interesting
-[                if input is not 0x01
+               restore character
>>              go to exit if
]
>[                else
<<.[-]          print and delete last character
<[<]>>[.>]      print all characters starting at the second
<[<]>[.[>]]     print first character and go to end if word is longer than one character
.               print null (space)
>>>             leave a zero cell and go to exit else
]
<+                set new else marker
<                 go to new input location
,                 input next character
]


If halting is not necessary:

# Aheui (esotope), 174 bytes

삭붵뱷뛰빠쇡붷뼤쎄투＠싼사쑫
ＢｙＬｅ쪼ｇｅｎ＠처쇠모코커
ＤＵＳＴ오멓＠＠＠＠푸셴쒼섣
＠＠＠＠쇡뽀＠＠＠삳멓＠샨＠맣


Try it online! press 'start' butten in TIO again to halt manually.

If halting is necessary:

# Aheui (esotope), 225 bytes

살뷕볙눠쀄삭붵뱷뛰빠쇡붷빠쎄투＠싼사쑫
Ｂｙ＠＠＠＠＠야빠속＠＠＠수처쇠모오어
Ｌｅｇｅｎ＠＠먷초더헤셜썰뻐푸쉰썬＠셛
ＤＵＳＴ＠＠솩뽀사뫼섁쀠우삳멓산멓


Try it online!

In this version, following space after input is necessary. fixed. Now it is OK to not finish with space.

# JavaScript (ES6), 68 bytes

s=>s.split(" ").map(e=>e[a=e.length-1]+e.substr(1,a)+e[0]).join(" ")


Ungolfed:

s=>                                                  //function declaration
s                                                  //input
.split(" ")                                       //array of words
.map(                                  //for each word
e=>                               //function declaration
e[a=e.length-1]+               //connect the last character,
e.substr(1,a)+ //middle substring,
e[0]                                                 //and the first character.
)                                                //then,
.join(" ")                                      //connect modified words back

• This does not work: TIO. The middle substr should have one less character: s=>s.split(' ').map(e=>e[a=e.length-1]+e.substr(1,a-1)+e[0]).join(' '). This still does not deal with single letter words. – Johan du Toit May 20 at 9:57
• fixed: s=>s.split(' ').map(e=>e[a=e.length-1]+e.substr(1,a-1)+(a?e[0]:"")).join(' ') – Johan du Toit May 20 at 11:48