¿Quién tiene una coma para un segundo nombre?

18

Su desafío es tomar un nombre (cadena) como entrada, como

Albert Einstein

y salida:

Einstein, Albert

Pseudocódigo:

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

Más casos de prueba:

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

Reglas

  • La entrada siempre coincidirá con la expresión regular ^([A-Z][a-z]+ )+([A-Z][a-z]+)$.
  • No necesita manejar nombres extraños , incluso si la salida es técnicamente incorrecta, aquí está bien.
  • El espacio en blanco al final / nueva línea está bien.
  • ¿Alguna pregunta? ¡Comenta abajo!
programador 5000
fuente
¿Se permiten espacios finales?
Value Ink
Cerré como engañado porque las soluciones pueden reemplazarse lecon descuido ,y usted tiene esta pregunta
Downgoat
2
@Downgoat Ese desafío especifica dos palabras, mientras que las soluciones a esto tienen que funcionar para muchas palabras arbitrariamente. Por lo que yo puedo decir, de las respuestas con enlaces TIO, sólo la solución serio da la respuesta correcta para esta pregunta sustitución lecon ,.
ngenisis
77
@Downgoat que uno tiene -4. Al menos cierra esa como un engaño de esto.
Stephen
1
¿Están bien los espacios finales?
Tom Carpenter

Respuestas:

10

05AB1E , 7 bytes

Código:

',ì#Áðý

Utiliza la codificación 05AB1E . Pruébalo en línea!

Explicación:

',ì         # Prepend the input to ","
   #        # Split on spaces
    Á       # Rotate every element one position to the right (wrapping)
     ðý     # Join the array by spaces
Adnan
fuente
1
Anteponer! Sabía que tenía que haber una manera de hacerlo en forma de lista.
Emigna
9

JavaScript (ES6), 34 bytes

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

Manifestación:

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

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

giro
fuente
8

Retina , 19 17 16 bytes

Editar: Gracias a Riker por guardar 3 bytes

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

Pruébalo en línea!

ngenisis
fuente
1
espera, (.+)funciona también para ambos.
Rɪᴋᴇʀ
No entiendo por qué estabas usando \wen primer lugar
theonlygusti
1
@theonlygusti Estoy más familiarizado con la coincidencia de patrones en Mathematica, que usa la coincidencia perezosa en lugar de la codiciosa.
ngenisis
7

Jalea , 7 bytes

;”,Ḳṙ-K

Pruébalo en línea!

No conozco a Jelly muy bien, pero al leer otras respuestas parecía que no usaban un algoritmo óptimo ... así que aquí está:

Explicación

;”,Ḳṙ-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
León
fuente
7

Vim, 10 bytes / pulsaciones de teclas

v$F dA, <esc>p

Pruébalo en línea!

DJMcMayhem
fuente
Agradable, pero luché para que funcionara, <esc>no aparece en su código. Para avisar a otros que quieran probar: Esto supone que el nombre está escrito en el editor y que actualmente se encuentra al principio del archivo en modo normal.
sigvaldm
7

V / vim, 9 8 bytes

$bD0Pa, 

Pruébalo en línea!

Guardado un byte gracias a

Tenga en cuenta que hay un carácter de espacio final. Deja un espacio final, que está permitido según las reglas.

Explicación:

$       " 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
fuente
¡Buena esa! Buena idea poner el modo de inserción al final para evitar la necesidad <esc>. Puede guardar un byte haciendo en $bDlugar de $diw. :)
DJMcMayhem
Gracias. $bDsin embargo, no maneja nombres de un carácter, le pregunté a OP si eso está permitido.
Kevin
Parece que es, así que actualizando.
Kevin
6

Mathematica, 52 40 bytes

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

C, 45 bytes

EDITAR: Acabo de notar el requisito de que la entrada posiblemente tenga más de dos palabras. Lo dejaré como está con una nota de que esto solo funciona para dos palabras.

EDITAR: eliminado \n. Agregue 2 bytes si lo considera necesario.

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

Compila con gcc name.cGCC 6.3.1. Ignorar las advertencias. Uso:

$./a.out Albert Einstein
Einstein, Albert

Abuso de lenguaje:

  • Tipo intde retorno implícito mainy nada devuelto.
  • Declaración implícita de printf. GCC lo incluirá de todos modos.
  • Tipo incorrecto de b. No importa con%s

Gracias a @ Khaled.K por los consejos sobre el uso en main(a,b)int**b;lugar de main(int a, int **b).

sigvaldm
fuente
Bonito primer golf, bienvenido al sitio web, también main(a,**b){printf("%s, %s",b[2],b[1]);}es de 40 bytes
Khaled.K
Gracias :) En realidad pensé en omitir los tipos por completo, pero por alguna razón no se compilaba.
sigvaldm
1
Esto funcionamain(a,b)int**b;{printf("%s, %s\n",b[2],b[1]);}
Khaled.K
4

sed, 19 + 1 para -E = 20 bytes

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

Debe usar -r (GNU) o -E (BSD, GNU recientes) para evitar tener que escapar del paréntesis de agrupación.

Si está escrito en la línea de comandos, debe estar entre comillas para evitar que el shell lo analice como tokens múltiples:

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

C, 68 bytes

Espero que no esté mal agregar otra publicación, pero aquí hay una solución ligeramente diferente a mi solución C publicada anteriormente. Este acepta cualquier número de nombres.

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

Compile con gcc name.c(GCC 6.3.1) e ignore las advertencias. Uso:

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

Gracias a @ Khaled.K por los consejos sobre main(a,b)int**b;

Gracias por el consejo sobre el bucle for a @Alkano.

sigvaldm
fuente
1
puedes ganar 2 bytes, usando for en lugar de while main(a,b)int**b;{for(printf("%s,",b[--a]);++b,--a;printf(" %s",*b));}
Alkano
Esto suena loco, pero puedes hacerlomain(a,b)int**b;{a&&printf("%s,"b[a-1])&&main(a-1,b);}
Khaled.K
Muy buenos trucos :) Nunca pensé en llamar a main de forma recursiva. Pero no funciona del todo. Su salida fue "Kennedy, Fitzgerald, John,. / A.out", sería una solución parcial main(a,b)int**b;{--a&&printf("%s, ",b[a])&&main(a,b);}. Es 2 bytes más corto y se asegura de que no imprima el nombre del programa, pero aún usa una coma entre cada nombre.
sigvaldm
3

Mathematica, 45 bytes

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

Se guardaron algunos bytes sobre la respuesta de ngenisis tomando la entrada como una lista de caracteres en lugar de como una cadena. Función pura que usa una regla de reemplazo de patrones.

Mathematica, 49 bytes

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

Otra función pura que toma una lista de caracteres como entrada y devuelve una lista de caracteres. Éste añade ","y " "a la entrada y luego gira la lista de caracteres hasta el último espacio se encuentra al final. (Por lo tanto, la salida tiene un espacio final, a diferencia de la primera función anterior).

Greg Martin
fuente
#/.{a__,s=" ",b:Except@s..}->{b,",",s,a}&es 4bytes más cortos, pero descubrí que no Exceptes necesario para los patrones de cadena, lo que me ahorra 12bytes.
ngenisis
ah, ¿elige automáticamente el más largo xen tu respuesta?
Greg Martin
Sí, la coincidencia de patrones de cadena es codiciosa, pero la coincidencia de patrones regular es perezosa.
ngenisis
agradable <agita la bandera blanca>
Greg Martin
3

C #, 76 72 bytes

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

Guardado 4 bytes con la ayuda de @KevinCruijssen

Versión antigua que usa subcadenas para 76 bytes:

s=>s.Substring(s.LastIndexOf(' ')+1)+", "+s.Substring(0,s.LastIndexOf(' '));
TheLethalCoder
fuente
1
Lástima que System.Text.RegularExpressions.Regexsea ​​tan largo en C # .. s=>new System.Text.RegularExpressions.Regex("(.+) (.+)").Replace(s,"$2, $1");es solo un byte más.
Kevin Cruijssen
1
@KevinCruijssen Es cierto, pero puedo usar el método estático Regexpara guardar 4 bytes
TheLethalCoder
3

Awk, 18 personajes

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

Ejecución de muestra:

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

Pruébalo en línea!

hombre trabajando
fuente
2

Jalea , 8 bytes

Ḳ©Ṫ”,⁶®K

Pruébalo en línea!

Hiperneutrino
fuente
Maldita sea, Ninja'd y outgolfed.
ATaco
@ATaco gg :) y ese es un ninja bastante grande.
HyperNeutrino
1
(Estaba jugando al golf, shhh)
ATaco
2

05AB1E , 9 bytes

#`',«.Áðý

Pruébalo en línea!

Explicación

#           # 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
fuente
Sí, probablemente debería unirme por comando espacial: p
Adnan
@Adnan: Sería bueno ver con qué frecuencia se usa :)
Emigna
2

Pyth , 11 bytes

jd.>c+z\,d1

Explicación:

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

¡Pruébalo en línea!

Jim
fuente
2

PHP, 45 bytes

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

Pruébalo en línea!

Jörg Hülsermann
fuente
1
¿Por qué en \pL+lugar de .+?
Kevin Cruijssen
@KevinCruijssen Tienes razón, la primera parte de la expresión regular es codiciosa, así que no importa usarla .o\pL
Jörg Hülsermann
2

MATLAB / Octave , 37 bytes

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

Pruébalo en línea!

Basado en la respuesta Retina de @ngenisis, también podemos jugar el juego de expresiones regulares tanto en Octave como en MATLAB, ahorrando unos pocos bytes sobre mi respuesta anterior.


Vieja respuesta:

Voy a dejar esta respuesta aquí también teniendo en cuenta que es una forma más única de hacerlo en comparación con una simple expresión regular.

Octava , 49 47 bytes

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

¡Inténtalo en línea!

Una función anónima para generar la salida.

Básicamente, el código primero encuentra el último espacio en la cadena usando b=find(a==32)(end). Luego toma la parte final de la cadena (después del espacio) usando a(b+1:end), donde bes la salida de encontrar el último espacio. También toma el inicio de la cadena con a(1:b-1), y concatena ambos junto con un ', 'en el medio.

Ya he guardado algunos bytes en comparación con el típico find(a==32,1,'last'). No estoy seguro de que haya mucho más para ahorrar.

Tom Carpenter
fuente
2

Jalea , 9 bytes

ḲµṪ;⁾, ;K

Explicado, 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.

Pruébalo en línea!

Probar en todos los casos de prueba.

Un taco
fuente
2

Python 3, 52 bytes

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

Muy simple, podría usar ayuda de golf. Simplemente pone la última palabra al frente y las une con ",".

Caso de prueba:

>>> 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
fuente
2

Java, 110 62 bytes

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

Método no estático.

-48 bytes gracias a Kevin Cruijssen

Hiperneutrino
fuente
String c(String s){int i=s.lastIndexOf(' ');return s.substring(i+1)+", "+s.substring(0,i);}es más corto ( 91 bytes ).
Kevin Cruijssen
Y String d(String s){return s.replaceAll("(.+) (.+)","$2, $1");}es aún más corto ( 62 bytes ).
Kevin Cruijssen
@KevinCruijssen Oh, Dios mío, agradable. ¡Gracias! Debería aprender a usar regex mejor: P
HyperNeutrino
2

PHP , 62 59 bytes

-3 bytes, gracias Jörg

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

Pruébalo en línea!

Solución anterior, 63 bytes

No funciona si la persona tiene 3 nombres repetidos.

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

Pruébalo en línea

YO
fuente
Puede usar en $argnlugar de$argv[1]
Jörg Hülsermann
2

Excel, 174 170 168 bytes

Guardado 2 bytes gracias a Wernisch

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

Esto no es elegante ni inteligente. Es un método bastante básico. Parece que debería haber una forma más corta con las fórmulas de matriz, pero no puedo encontrar una que funcione.

Tostadas de ingeniero
fuente
La solución solo funciona para casos donde hay tres nombres. No maneja "Albert Einstein" por ejemplo.
Wernisch
@Wernisch Gracias! Debería funcionar ahora.
Ingeniero Toast
El espacio en blanco al final se permite según la pregunta. Piensa que puedes ahorrar 2 bytes al dejar de lado la -1función LEFT.
Wernisch
1

JS (ES6), 52 44 bytes

i=>(i=i.split` `,l=i.pop(),l+", "+i.join` `)
programador 5000
fuente
1

MATL , 10 bytes

44hYb1YSZc

Pruébalo en línea!

Explicación

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
fuente
1

Gema, 23 personajes

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

Lo único notable aquí es cómo el desafío logró golpear la debilidad de la no codicia de los patrones Gema.

Ejecución de muestra:

bash-4.4$ echo -n 'John Fitzgerald Kennedy' | gema '* =@append{s; *};\Z=,$s'
Kennedy, John Fitzgerald
hombre trabajando
fuente