19
\$\begingroup\$

Your challenge is to take a name (string) as input, like

Albert Einstein

and output:

Einstein, Albert

Pseudocode:

set in to input
set arr to in split by " "
set last to the last element of arr
remove the last element of arr
set out to arr joined with " "
prepend ", " to out
prepend last to out
output out

More test cases:

John Fitzgerald Kennedy => Kennedy, John Fitzgerald
Abraham Lincoln => Lincoln, Abraham

Rules

  • The input will always match the regex ^([A-Z][a-z]+ )+([A-Z][a-z]+)$.
  • You don't need to handle weird names, even if the output is technically incorrect it is fine here.
  • Trailing whitespace / newline is OK.
  • Any questions? Comment below!
\$\endgroup\$
15
  • \$\begingroup\$ Are trailing spaces allowed? \$\endgroup\$
    – Value Ink
    May 24, 2017 at 1:55
  • \$\begingroup\$ I closed as dupe because solutions can pretty much siply replace le with , and you have this question \$\endgroup\$
    – Downgoat
    May 24, 2017 at 2:19
  • 2
    \$\begingroup\$ @Downgoat That challenge specifies two words, whereas solutions to this have to work for arbitrarily many words. As far as I can tell, of the answers with TIO links, only the Seriously solution gives the correct answer for this question substituting le with ,. \$\endgroup\$
    – user61980
    May 24, 2017 at 2:47
  • 7
    \$\begingroup\$ @Downgoat that one has -4. At least close that one as a dupe of this. \$\endgroup\$
    – Stephen
    May 24, 2017 at 2:58
  • 1
    \$\begingroup\$ Are trailing spaces ok? \$\endgroup\$ May 24, 2017 at 7:43

46 Answers 46

10
\$\begingroup\$

05AB1E, 7 bytes

Code:

',ì#Áðý

Uses the 05AB1E encoding. Try it online!

Explanation:

',ì         # Prepend the input to ","
   #        # Split on spaces
    Á       # Rotate every element one position to the right (wrapping)
     ðý     # Join the array by spaces
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Prepend! I knew there had to be a way to do it in listform. \$\endgroup\$
    – Emigna
    May 24, 2017 at 7:13
8
\$\begingroup\$

JavaScript (ES6), 34 bytes

s=>s.replace(/(.+) (.+)/,'$2, $1')

Demo:

let f = s=>s.replace(/(.+) (.+)/,'$2, $1')

;[ 'Albert Einstein', 'John Fitzgerald Kennedy', 'Abraham Lincoln' ].forEach(
  s => console.log(`${s} => ${f(s)}`)
)

\$\endgroup\$
7
\$\begingroup\$

Retina, 19 17 16 bytes

Edit: Thanks to Riker for saving 3 bytes

(.+) (.+)
$2, $1

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ hold up, (.+) works too for both. \$\endgroup\$
    – Riker
    May 24, 2017 at 2:19
  • \$\begingroup\$ I don't understand why you were using \w in the first place \$\endgroup\$ May 24, 2017 at 13:38
  • 1
    \$\begingroup\$ @theonlygusti I'm more familiar with pattern matching in Mathematica, which uses lazy matching rather than greedy. \$\endgroup\$
    – user61980
    May 24, 2017 at 17:43
6
\$\begingroup\$

Jelly, 7 bytes

;”,Ḳṙ-K

Try it online!

I don't know Jelly very well, but reading other answers it looked like they didn't use an optimal algorithm... so here it is:

Explanation

;”,Ḳṙ-K
;”,        Append a comma to the end of the string
   Ḳ       Split on spaces
    ṙ-     Rotate the array by -1 (1 time towards the right)
      K    Join with spaces
\$\endgroup\$
6
\$\begingroup\$

V / vim, 9 8 bytes

$bD0Pa, 

Try it online!

Saved one Byte thanks to

Note there is a trailing space character. Leaves a trailing space, which is allowed per the rules.

Explanation:

$       " move the cursor to the end of the line
 b      " move the cursor to the beginning of the current word
  D     " delete to the end of the line
   0    " move the cursor to the start of the line
    P   " paste in front of the cursor.
     a  " append (enter insert mode with the cursor one character forward)
      , " Literal text, ", "
\$\endgroup\$
3
  • \$\begingroup\$ Nice one! Good thinking putting the insert mode at the end to avoid needing <esc>. You can save one byte by doing $bD instead of $diw. :) \$\endgroup\$
    – DJMcMayhem
    May 25, 2017 at 16:34
  • \$\begingroup\$ Thanks. $bD doesn't handle one-character names though, I've asked OP if that's allowed. \$\endgroup\$
    – Kevin
    May 25, 2017 at 16:43
  • \$\begingroup\$ Looks like it is, so updating. \$\endgroup\$
    – Kevin
    May 25, 2017 at 16:48
5
\$\begingroup\$

Python 2, 39 bytes

f,l=input().rsplit(' ',1);print l+',',f

Try it online!

Yup, rsplit.

\$\endgroup\$
1
  • \$\begingroup\$ @UbdusSamad We allow Python's input instead of raw_input for golfing - see this meta post \$\endgroup\$
    – Stephen
    May 26, 2017 at 4:29
5
\$\begingroup\$

Mathematica, 52 40 bytes

StringReplace[x__~~" "~~y__:>y<>", "<>x]
\$\endgroup\$
5
\$\begingroup\$

Vim, 10 bytes/keystrokes

v$F dA, <esc>p

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice one, but I struggled to get it working, <esc> doesn't show up in your code. For notice to others who want to try: This assumes that the name is written in the editor and that you're currently at the beginning of the file in normal mode. \$\endgroup\$
    – sigvaldm
    May 25, 2017 at 7:40
4
\$\begingroup\$

><>, 27 bytes

i:0(?v
" ,"~<^r/
=" ":}o!/?

Try it online!

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

C, 45 bytes

EDIT: I just now noticed the requirement for the input possibly having more than two words. I'll leave it as-is with a note that this only works for two words.

EDIT: removed \n. Add 2 bytes if you consider it necessary.

main(a,b)int**b;{printf("%s, %s",b[2],b[1]);}

Compiles with gcc name.c, GCC 6.3.1. Ignore warnings. Usage:

$./a.out Albert Einstein
Einstein, Albert

Abuse of language:

  • Implicit return type int of main and nothing returned.
  • Implicit declaration of printf. GCC will include it anyway.
  • Wrong type of b. Doesn't matter with %s

Thanks to @Khaled.K for the tips on using main(a,b)int**b; rather than main(int a, int **b).

\$\endgroup\$
3
  • \$\begingroup\$ Nice first golf, welcome to the website, also main(a,**b){printf("%s, %s",b[2],b[1]);} is 40 bytes \$\endgroup\$
    – Khaled.K
    May 24, 2017 at 7:56
  • \$\begingroup\$ Thanks :) I actually thought about omitting the types completely, but for some reason it wouldn't compile. \$\endgroup\$
    – sigvaldm
    May 24, 2017 at 7:58
  • 1
    \$\begingroup\$ This works main(a,b)int**b;{printf("%s, %s\n",b[2],b[1]);} \$\endgroup\$
    – Khaled.K
    May 24, 2017 at 8:01
3
\$\begingroup\$

Ruby, 22 bytes

->s{s[/\w+$/]+", #$`"}

Try it online!

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

sed, 19 + 1 for -E = 20 bytes

s/(.*) (.*)/\2, \1/

Must use -r (GNU) or -E (BSD, recent GNUs) to avoid having to escape the grouping parenthesis.

If written on the command-line, must be enclosed in quotes to avoid being parsed as multiple tokens by the shell :

sed -E 's/(.*) (.*)/\2, \1/'
\$\endgroup\$
3
\$\begingroup\$

C, 68 bytes

Hope it's not wrong to add another post but here's a slightly different solution than my previously posted C solution. This one accepts any number of names.

main(a,b)int**b;{for(printf("%s,",b[--a]);--a;printf(" %s",*++b));}

Compile with gcc name.c (GCC 6.3.1) and ignore warnings. Usage:

$./a.out John Fitzgerald Kennedy
Kennedy, John Fitzgerald

Thanks to @Khaled.K for the tips on main(a,b)int**b;

Thanks for the tip on the for loop to @Alkano.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ you can gain 2 bytes, by using for instead of while main(a,b)int**b;{for(printf("%s,",b[--a]);++b,--a;printf(" %s",*b));} \$\endgroup\$
    – Alkano
    May 24, 2017 at 9:03
  • \$\begingroup\$ This sounds crazy, but you can do this main(a,b)int**b;{a&&printf("%s,"b[a-1])&&main(a-1,b);} \$\endgroup\$
    – Khaled.K
    May 25, 2017 at 6:02
  • \$\begingroup\$ Very nice tricks :) I never thought about calling main recursively. But it doesn't quite work. It's output was "Kennedy,Fitzgerald,John,./a.out," A partial solution would be main(a,b)int**b;{--a&&printf("%s, ",b[a])&&main(a,b);}. It's 2 bytes shorter, and it makes sure you don't print the program name, but it still uses comma between each name. \$\endgroup\$
    – sigvaldm
    May 25, 2017 at 7:19
2
\$\begingroup\$

Mathematica, 45 bytes

#/.{a__,s=" ",b__}/;{b}~FreeQ~s->{b,",",s,a}&

Saved a few bytes over ngenisis's answer by taking input as a list of characters rather than as a string. Pure function that uses a pattern-replacement rule.

Mathematica, 49 bytes

#~Join~{","," "}~RotateLeft~Last@Position[#," "]&

Another pure function taking a list of characters as input and returning a list of characters. This one appends "," and " " to the input and then rotates the list of characters until the last space is at the end. (Thus the output has a trailing space, unlike the first function above.)

\$\endgroup\$
4
  • \$\begingroup\$ #/.{a__,s=" ",b:Except@s..}->{b,",",s,a}& is 4 bytes shorter, but I found out that the Except is unnecessary for string patterns, saving me 12 bytes. \$\endgroup\$
    – user61980
    May 24, 2017 at 17:41
  • \$\begingroup\$ ah, does it automatically choose the longest x in your answer? \$\endgroup\$ May 24, 2017 at 19:16
  • \$\begingroup\$ Yep, string pattern matching is greedy but regular pattern matching is lazy. \$\endgroup\$
    – user61980
    May 24, 2017 at 19:17
  • \$\begingroup\$ nice <waves white flag> \$\endgroup\$ May 24, 2017 at 19:18
2
\$\begingroup\$

C#, 76 72 bytes

s=>System.Text.RegularExpressions.Regex.Replace(s,"(.+) (.+)","$2, $1");

Saved 4 bytes with the help of @KevinCruijssen

Old version using substrings for 76 bytes:

s=>s.Substring(s.LastIndexOf(' ')+1)+", "+s.Substring(0,s.LastIndexOf(' '));
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Too bad System.Text.RegularExpressions.Regex is so damn long in C#.. s=>new System.Text.RegularExpressions.Regex("(.+) (.+)").Replace(s,"$2, $1"); is just one byte more. \$\endgroup\$ May 24, 2017 at 9:35
  • 1
    \$\begingroup\$ @KevinCruijssen True but I can use the static method on Regex to save 4 bytes \$\endgroup\$ May 24, 2017 at 9:38
2
\$\begingroup\$

Awk, 18 characters

{$1=$NF", "$1}NF--

Sample run:

bash-4.4$ awk '{$1=$NF", "$1}NF--' <<< 'John Fitzgerald Kennedy'
Kennedy, John Fitzgerald

Try it online!

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

JS (ES6), 52 44 bytes

i=>(i=i.split` `,l=i.pop(),l+", "+i.join` `)
\$\endgroup\$
0
1
\$\begingroup\$

Jelly, 8 bytes

Ḳ©Ṫ”,⁶®K

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Damnit, Ninja'd and outgolfed. \$\endgroup\$
    – ATaco
    May 24, 2017 at 1:57
  • \$\begingroup\$ @ATaco gg :) and that is a pretty big ninja. \$\endgroup\$
    – hyper-neutrino
    May 24, 2017 at 1:59
  • 1
    \$\begingroup\$ (I was golfing, shhh) \$\endgroup\$
    – ATaco
    May 24, 2017 at 1:59
1
\$\begingroup\$

05AB1E, 9 bytes

#`',«.Áðý

Try it online!

Explanation

#           # split input on spaces
 `          # push each name separately to stack
  ',«       # concatenate a comma to the last name
     .Á     # rotate stack right
       ðý   # join stack by spaces
\$\endgroup\$
2
  • \$\begingroup\$ Yeah, I should probably make a join by space command :p \$\endgroup\$
    – Adnan
    May 24, 2017 at 6:59
  • \$\begingroup\$ @Adnan: Would be nice seeing how often it's used :) \$\endgroup\$
    – Emigna
    May 24, 2017 at 7:11
1
\$\begingroup\$

Pyth, 11 bytes

jd.>c+z\,d1

Explanation:

jd.>c+z\,d1
     +z\,      Append the "," to the input
    c+z\,d     Split the string on " "
  .>c+z\,d1    Rotate the array one element right
jd.>c+z\,d1    Join the array on " "

Test it online!

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

PHP, 45 Bytes

<?=preg_filter("#(.*) (.+)#","$2, $1",$argn);

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Why \pL+ instead of .+? \$\endgroup\$ May 24, 2017 at 9:37
  • \$\begingroup\$ @KevinCruijssen You are right the first part of the regex is greedy so it does not matter to use . or \pL \$\endgroup\$ May 24, 2017 at 9:57
1
\$\begingroup\$

Bash, 26 bytes

echo ${!#}, ${@:1:$[$#-1]}

Try it online!

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

MATLAB/Octave, 37 bytes

@(a)regexprep(a,'(.+) (.+)','$2, $1')

Try it online!

Based on @ngenisis' Retina answer, we can also play the regex game in both Octave and MATLAB, saving a fair few bytes over my previous answer.


Old Answer:

I'm going to leave this answer here as well considering it is a more unique way of doing it compared to a simple regex.

Octave, 49 47 bytes

@(a)[a((b=find(a==32)(end))+1:end) ', ' a(1:b)]

Old try it online!

An anonymous function to generate the output.

Basically the code first finds the last space in the string using b=find(a==32)(end). Then It takes the end part of the string (after the space) using a(b+1:end), where b is the output of finding the last space. It also takes the start of the string with a(1:b-1), and concatenates both together with a ', ' in between.

I've already saved a few bytes vs the typical find(a==32,1,'last'). Not quite sure there is much more to save.

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

Jelly, 9 bytes

ḲµṪ;⁾, ;K

Explained, ish:

ḲµṪ;⁾, ;K
Ḳ           # Split the input by spaces
 µ          # Separate the link into two chains. Essentially calls the right half with the split string monadically.
  Ṫ         # The last element, (The last name), modifying the array.
   ;        # Concatenated with...
    ⁾,      # The string literal; ", "
       ;    # Concatenated with...
        K   # The rest of the array, joined at spaces.

Try it online!

Try on all test cases.

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

Python 3, 52 bytes

lambda s:s.split()[-1]+", "+" ".join(s.split()[:-1])

Very simple, could use golfing help. Just puts the last word at the front and joins them with ", ".

Testcase:

>>> f=lambda s:s.split()[-1]+", "+" ".join(s.split()[:-1])
>>> f("Monty Python")
'Python, Monty'
>>> f("Albus Percival Wulfric Brian Dumbledore")
'Dumbledore, Albus Percival Wulfric Brian'
\$\endgroup\$
1
\$\begingroup\$

Japt, 14 bytes

U+', q'  é q' 

A port of @programmer5000's JavaScript answer.

Try it online!

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

Java, 110 62 bytes

String d(String s){return s.replaceAll("(.+) (.+)","$2, $1");}

Non-static method.

-48 bytes thanks to Kevin Cruijssen

\$\endgroup\$
3
  • \$\begingroup\$ String c(String s){int i=s.lastIndexOf(' ');return s.substring(i+1)+", "+s.substring(0,i);} is shorter (91 bytes). \$\endgroup\$ May 24, 2017 at 9:10
  • \$\begingroup\$ And String d(String s){return s.replaceAll("(.+) (.+)","$2, $1");} is even shorter (62 bytes). \$\endgroup\$ May 24, 2017 at 9:14
  • \$\begingroup\$ @KevinCruijssen Oh geez nice. Thanks! I should learn to use regex better :P \$\endgroup\$
    – hyper-neutrino
    May 25, 2017 at 12:41
1
\$\begingroup\$

Perl 18+1=19 bytes

perl -pe '/\S+$/;$_="$&, $`"'

+1 for -p

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

PHP, 62 59 bytes

-3 bytes, thanks Jörg

$a=explode(' ',$argn);echo array_pop($a).', '.join(' ',$a);

Try it online!

Old solution, 63 Bytes

Doesn't work if the person has 3 repeating names.

<?=($a=strrchr($argv[1]," ")).", ".str_replace($a,'',$argv[1]);

Try it online

\$\endgroup\$
1
  • \$\begingroup\$ You can use $argn instead of $argv[1] \$\endgroup\$ May 29, 2017 at 15:03
1
\$\begingroup\$

Vim, 6 keystrokes

i<C-p>, <End><C-w>

Leaves a trailing space character, which is allowed by the rules

Explanation:
i      Enter insert mode
<C-p>  Autocomplete with last word
,      Write ", "
<End>  Move the cursor to the end of the line
<C-w>  Delete the word behind the cursor
\$\endgroup\$
0

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.