Qui a une virgule pour un deuxième prénom?

18

Votre défi est de prendre un nom (chaîne) en entrée, comme

Albert Einstein

et sortie:

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

Plus de cas de test:

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

Règles

  • L'entrée correspondra toujours à l'expression régulière ^([A-Z][a-z]+ )+([A-Z][a-z]+)$.
  • Vous n'avez pas besoin de gérer des noms étranges , même si la sortie est techniquement incorrecte, c'est bien ici.
  • L'espace de fin / la nouvelle ligne est OK.
  • Des questions? Commentaires ci-dessous!
programmer5000
la source
Les espaces de fin sont-ils autorisés?
Value Ink
J'ai fermé comme dupe parce que les solutions peuvent à peu près remplacer lepar ,et vous avez cette question
Downgoat
2
@Downgoat Ce défi spécifie deux mots, alors que les solutions doivent fonctionner pour arbitrairement plusieurs mots. Pour autant que je sache, des réponses avec des liens TIO, seule la solution Sérieusement donne la bonne réponse à cette question en remplaçant lepar ,.
ngenisis
7
@Downgoat que l'on a -4. Au moins, fermez celui-là comme une dupe de cela.
Stephen
1
Les espaces de fuite sont-ils corrects?
Tom Carpenter

Réponses:

10

05AB1E , 7 octets

Code:

',ì#Áðý

Utilise l' encodage 05AB1E . Essayez-le en ligne!

Explication:

',ì         # Prepend the input to ","
   #        # Split on spaces
    Á       # Rotate every element one position to the right (wrapping)
     ðý     # Join the array by spaces
Adnan
la source
1
Préparez! Je savais qu'il devait y avoir un moyen de le faire sous forme de liste.
Emigna
9

JavaScript (ES6), 34 octets

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

Démo:

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

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

gyre
la source
8

Rétine , 19 17 16 octets

Edit: Merci à Riker pour avoir économisé 3 octets

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

Essayez-le en ligne!

ngenisis
la source
1
tenez bon, (.+)ça marche aussi pour les deux.
Rɪᴋᴇʀ
Je ne comprends pas pourquoi vous utilisiez \wen premier lieu
theonlygusti
1
@theonlygusti Je connais mieux la correspondance de motifs dans Mathematica, qui utilise la correspondance paresseuse plutôt que gourmande.
ngenisis
7

Gelée , 7 octets

;”,Ḳṙ-K

Essayez-le en ligne!

Je ne connais pas très bien Jelly, mais en lisant d'autres réponses, il semblait qu'ils n'utilisaient pas d'algorithme optimal ... alors voici:

Explication

;”,Ḳṙ-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
Leo
la source
7

Vim, 10 octets / touches

v$F dA, <esc>p

Essayez-le en ligne!

DJMcMayhem
la source
Bien, mais j'ai eu du mal à le faire fonctionner, <esc>n'apparaît pas dans votre code. Pour avis à ceux qui veulent essayer: Cela suppose que le nom est écrit dans l'éditeur et que vous êtes actuellement au début du fichier en mode normal.
sigvaldm
7

V / vim, 9 8 octets

$bD0Pa, 

Essayez-le en ligne!

Un octet enregistré grâce à

Notez qu'il y a un caractère d'espace de fin. Laisse un espace de fin, ce qui est autorisé par les règles.

Explication:

$       " 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, ", "
Kevin
la source
Joli! Bonne idée de mettre le mode d'insertion à la fin pour éviter d'avoir besoin <esc>. Vous pouvez enregistrer un octet en faisant $bDau lieu de $diw. :)
DJMcMayhem
Merci. $bDne gère pas les noms à un caractère, j'ai demandé à OP si cela est autorisé.
Kevin
On dirait que c'est le cas, donc mise à jour.
Kevin
6

Mathematica, 52 40 octets

StringReplace[x__~~" "~~y__:>y<>", "<>x]
ngenisis
la source
5

C, 45 octets

EDIT: Je viens de remarquer la nécessité pour l'entrée d'avoir éventuellement plus de deux mots. Je vais le laisser tel quel avec une note que cela ne fonctionne que pour deux mots.

EDIT: supprimé \n. Ajoutez 2 octets si vous le jugez nécessaire.

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

Compile avec gcc name.c, GCC 6.3.1. Ignorez les avertissements. Usage:

$./a.out Albert Einstein
Einstein, Albert

Abus de langage:

  • Type intde retour implicite de mainet rien n'est retourné.
  • Déclaration implicite de printf. GCC l'inclura de toute façon.
  • Mauvais type de b. Peu importe avec%s

Merci à @ Khaled.K pour les conseils d'utilisation main(a,b)int**b;plutôt que main(int a, int **b).

sigvaldm
la source
Beau premier golf, bienvenue sur le site, main(a,**b){printf("%s, %s",b[2],b[1]);}est également de 40 octets
Khaled.K
Merci :) J'ai en fait pensé à omettre complètement les types, mais pour une raison quelconque, cela ne se compilerait pas.
sigvaldm
1
Cela fonctionnemain(a,b)int**b;{printf("%s, %s\n",b[2],b[1]);}
Khaled.K
4

sed, 19 + 1 pour -E = 20 octets

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

Doit utiliser -r (GNU) ou -E (BSD, GNU récents) pour éviter d'avoir à échapper à la parenthèse de regroupement.

S'il est écrit sur la ligne de commande, doit être placé entre guillemets pour éviter d'être analysé en tant que jetons multiples par le shell:

sed -E 's/(.*) (.*)/\2, \1/'
Aaron
la source
4

C, 68 octets

J'espère que ce n'est pas faux d'ajouter un autre message, mais voici une solution légèrement différente de ma solution C précédemment publiée. Celui-ci accepte n'importe quel nombre de noms.

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

Compilez avec gcc name.c(GCC 6.3.1) et ignorez les avertissements. Usage:

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

Merci à @ Khaled.K pour les conseils sur main(a,b)int**b;

Merci pour le conseil sur la boucle for à @Alkano.

sigvaldm
la source
1
vous pouvez gagner 2 octets, en utilisant for au lieu de while main(a,b)int**b;{for(printf("%s,",b[--a]);++b,--a;printf(" %s",*b));}
Alkano
Cela semble fou, mais vous pouvez le fairemain(a,b)int**b;{a&&printf("%s,"b[a-1])&&main(a-1,b);}
Khaled.K
Très belles astuces :) Je n'ai jamais pensé à appeler récursivement main. Mais ça ne marche pas tout à fait. Sa sortie était "Kennedy, Fitzgerald, John,. / A.out," Une solution partielle serait main(a,b)int**b;{--a&&printf("%s, ",b[a])&&main(a,b);}. Il est plus court de 2 octets, et il s'assure que vous n'imprimez pas le nom du programme, mais il utilise toujours une virgule entre chaque nom.
sigvaldm
3

Mathematica, 45 octets

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

Enregistré quelques octets sur la réponse de ngenisis en prenant l'entrée comme une liste de caractères plutôt que comme une chaîne. Fonction pure qui utilise une règle de remplacement de modèle.

Mathematica, 49 octets

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

Une autre fonction pure prenant une liste de caractères en entrée et renvoyant une liste de caractères. Celui-ci ajoute ","et " "à l'entrée, puis fait pivoter la liste des caractères jusqu'à ce que le dernier espace soit à la fin. (Ainsi, la sortie a un espace de fin, contrairement à la première fonction ci-dessus.)

Greg Martin
la source
#/.{a__,s=" ",b:Except@s..}->{b,",",s,a}&est 4octets plus court, mais j'ai découvert que le Exceptn'est pas nécessaire pour les modèles de chaîne, me faisant économiser des 12octets.
ngenisis
ah, choisit-il automatiquement le plus long xdans votre réponse?
Greg Martin
Oui, la correspondance des motifs de chaîne est gourmande, mais la correspondance régulière des motifs est paresseuse.
ngenisis
beau <vagues drapeau blanc>
Greg Martin
3

C #, 76 72 octets

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

Enregistré 4 octets avec l'aide de @KevinCruijssen

Ancienne version utilisant des sous-chaînes pour 76 octets:

s=>s.Substring(s.LastIndexOf(' ')+1)+", "+s.Substring(0,s.LastIndexOf(' '));
TheLethalCoder
la source
1
Dommage, System.Text.RegularExpressions.Regexc'est tellement long en C # .. s=>new System.Text.RegularExpressions.Regex("(.+) (.+)").Replace(s,"$2, $1");n'est qu'un octet de plus.
Kevin Cruijssen
1
@KevinCruijssen True mais je peux utiliser la méthode statique Regexpour enregistrer 4 octets
TheLethalCoder
3

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!

manatwork
la source
2

Jelly, 8 bytes

Ḳ©Ṫ”,⁶®K

Try it online!

HyperNeutrino
la source
Damnit, Ninja'd and outgolfed.
ATaco
@ATaco gg :) and that is a pretty big ninja.
HyperNeutrino
1
(I was golfing, shhh)
ATaco
2

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
Emigna
la source
Yeah, I should probably make a join by space command :p
Adnan
@Adnan: Would be nice seeing how often it's used :)
Emigna
2

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!

Jim
la source
2

PHP, 45 Bytes

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

Try it online!

Jörg Hülsermann
la source
1
Why \pL+ instead of .+?
Kevin Cruijssen
@KevinCruijssen You are right the first part of the regex is greedy so it does not matter to use . or \pL
Jörg Hülsermann
2

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.

Tom Carpenter
la source
2

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.

ATaco
la source
2

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'
OldBunny2800
la source
2

Java, 110 62 bytes

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

Non-static method.

-48 bytes thanks to Kevin Cruijssen

HyperNeutrino
la source
String c(String s){int i=s.lastIndexOf(' ');return s.substring(i+1)+", "+s.substring(0,i);} is shorter (91 bytes).
Kevin Cruijssen
And String d(String s){return s.replaceAll("(.+) (.+)","$2, $1");} is even shorter (62 bytes).
Kevin Cruijssen
@KevinCruijssen Oh geez nice. Thanks! I should learn to use regex better :P
HyperNeutrino
2

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

M.E
la source
You can use $argn instead of $argv[1]
Jörg Hülsermann
2

Excel, 174 170 168 bytes

Saved 2 bytes thanks to Wernisch

=MID(A1,FIND("^",SUBSTITUTE(A1," ","^",LEN(A1)-LEN(SUBSTITUTE(A1," ",""))))+1,LEN(A1))&", "&LEFT(A1,FIND("^",SUBSTITUTE(A1," ","^",LEN(A1)-LEN(SUBSTITUTE(A1," ","")))))

This is not fancy or clever. It's a fairly basic method. It feels like there should be a shorter way with array formulas but I can't find one that works.

Engineer Toast
la source
Solution only works for cases where there three names. Does not handle "Albert Einstein" for example.
Wernisch
@Wernisch Thanks! It should work now.
Engineer Toast
Trailing whitespace is allowed according to question. Think you can save 2 bytes by leaving out the the -1 in the LEFT function.
Wernisch
1

JS (ES6), 52 44 bytes

i=>(i=i.split` `,l=i.pop(),l+", "+i.join` `)
programmer5000
la source
1

MATL, 10 bytes

44hYb1YSZc

Try it online!

Explanation

44h    % Implicitly input a string. Postpend a comma
       % STACK: 'John Fitzgerald Kennedy,'
Yb     % Split on spaces
       % STACK: {'John', 'Fitzgerald', 'Kennedy,'}
1YS    % Circularly shift 1 step to the right
       % STACK: {'Kennedy,', 'John', 'Fitzgerald'}
Zc     % Join with spaces between. Implicitly display
       % STACK: 'Kennedy, John Fitzgerald'
Luis Mendo
la source
1

Gema, 23 characters

* =@append{s; *}
\Z=,$s

The only remarkable thing here is how the challenge managed to hit the weakness of the Gema patterns non-greediness.

Sample run:

bash-4.4$ echo -n 'John Fitzgerald Kennedy' | gema '* =@append{s; *};\Z=,$s'
Kennedy, John Fitzgerald
manatwork
la source