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!

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

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


8

Rétine , 19 17 16 octets

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

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

Essayez-le en ligne!


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

7

Vim, 10 octets / touches

v$F dA, <esc>p

Essayez-le en ligne!


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, ", "

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]


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


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/'

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.


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


#/.{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(' '));

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!



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

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!



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.


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.


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'


2

Java, 110 62 bytes

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

Non-static method.

-48 bytes thanks to Kevin Cruijssen


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


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.


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

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'

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.