Quem tem uma vírgula para um nome do meio?

18

Seu desafio é usar um nome (string) como entrada, como

Albert Einstein

e saída:

Einstein, Albert

Pseudo-có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

Mais casos de teste:

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

Regras

  • A entrada sempre corresponderá ao regex ^([A-Z][a-z]+ )+([A-Z][a-z]+)$.
  • Você não precisa lidar com nomes estranhos , mesmo que a saída seja tecnicamente incorreta, tudo bem aqui.
  • O espaço em branco / nova linha à direita está OK.
  • Alguma pergunta? Comente abaixo!
programmer5000
fonte
Os espaços à direita são permitidos?
Value Ink
Fechei como joguete porque as soluções pode muito bem siply substituir lecom ,e você tem essa questão
Downgoat
2
@Downgoat Esse desafio especifica duas palavras, enquanto as soluções para isso precisam funcionar para muitas palavras arbitrariamente. Tanto quanto posso dizer, das respostas com links TIO, apenas a solução Seriously fornece a resposta correta para essa pergunta, substituindo- lea ,.
Ngenisis
7
@Downgoat esse tem -4. Pelo menos feche esse como um burro disso.
24517 Stephen
1
Os espaços à direita estão ok?
Tom Carpenter

Respostas:

10

05AB1E , 7 bytes

Código:

',ì#Áðý

Usa a codificação 05AB1E . Experimente online!

Explicação:

',ì         # Prepend the input to ","
   #        # Split on spaces
    Á       # Rotate every element one position to the right (wrapping)
     ðý     # Join the array by spaces
Adnan
fonte
1
Anexar! Eu sabia que tinha que haver uma maneira de fazê-lo em forma de lista.
Emigna
9

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

giro
fonte
8

Retina , 19 17 16 bytes

Edit: Obrigado ao Riker por salvar 3 bytes

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

Experimente online!

ngenisis
fonte
1
espera, (.+)funciona também para ambos.
Rɪᴋᴇʀ
Eu não entendo por que você estava usando \w, em primeiro lugar
theonlygusti
1
@theonlygusti Estou mais familiarizado com a correspondência de padrões no Mathematica, que usa correspondência lenta e não gananciosa.
Ngenisis
7

Geléia , 7 bytes

;”,Ḳṙ-K

Experimente online!

Eu não conheço Jelly muito bem, mas ao ler outras respostas, parecia que eles não usavam um algoritmo ideal ... então aqui está:

Explicação

;”,Ḳṙ-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
fonte
7

Vim, 10 bytes / pressionamentos de tecla

v$F dA, <esc>p

Experimente online!

DJMcMayhem
fonte
Legal, mas lutei para fazê-lo funcionar, <esc>não aparece no seu código. Para aviso para outras pessoas que desejam tentar: Isso pressupõe que o nome esteja escrito no editor e que você esteja no início do arquivo no modo normal.
Sigvaldm 25/05
7

V / vim, 9 8 bytes

$bD0Pa, 

Experimente online!

Guardou um byte graças a

Observe que há um caractere de espaço à direita. Deixa um espaço à direita, permitido pelas regras.

Explicação:

$       " 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
fonte
Agradável! É bom pensar em colocar o modo de inserção no final para evitar a necessidade <esc>. Você pode salvar um byte ao $bDinvés de $diw. :)
DJMcMayhem
Obrigado. $bDnão lida com nomes de um caractere, perguntei ao OP se isso é permitido.
25717 Kevin
Parece que é, então atualizando.
25417 Kevin
6

Mathematica, 52 40 bytes

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

C, 45 bytes

Edição: Acabei de notar o requisito para a entrada possivelmente com mais de duas palavras. Vou deixar como está com uma nota de que isso só funciona para duas palavras.

EDIT: removido \n. Adicione 2 bytes se considerar necessário.

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

Compila com gcc name.c, GCC 6.3.1. Ignore avisos. Uso:

$./a.out Albert Einstein
Einstein, Albert

Abuso de linguagem:

  • Tipo intde retorno implícito maine nada retornado.
  • Declaração implícita de printf. O GCC o incluirá de qualquer maneira.
  • Tipo errado de b. Não importa com%s

Agradecemos a @ Khaled.K pelas dicas de uso em main(a,b)int**b;vez de main(int a, int **b).

sigvaldm
fonte
Primeiro golf agradável, bem-vindo ao site, também main(a,**b){printf("%s, %s",b[2],b[1]);}é de 40 bytes
Khaled.K
Obrigado :) Na verdade, pensei em omitir completamente os tipos, mas por algum motivo não seria compilado.
Sigvaldm
1
Isso 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/

É necessário usar -r (GNU) ou -E (BSD, GNUs recentes) para evitar a necessidade de escapar do parêntese de agrupamento.

Se escrito na linha de comando, deve ser colocado entre aspas para evitar ser analisado como vários tokens pelo shell:

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

C, 68 bytes

Espero que não seja errado adicionar outro post, mas aqui está uma solução ligeiramente diferente da minha solução C postada anteriormente. Este aceita qualquer número de nomes.

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

Compile com gcc name.c(GCC 6.3.1) e ignore os avisos. Uso:

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

Obrigado a @ Khaled.K pelas dicas sobre main(a,b)int**b;

Obrigado pela dica no loop for do @Alkano.

sigvaldm
fonte
1
você pode ganhar 2 bytes, usando para, em vez de ao mesmo tempo main(a,b)int**b;{for(printf("%s,",b[--a]);++b,--a;printf(" %s",*b));}
alcano
Isso parece loucura, mas você pode fazer issomain(a,b)int**b;{a&&printf("%s,"b[a-1])&&main(a-1,b);}
Khaled.K
Truques muito agradáveis ​​:) Eu nunca pensei em chamar main recursivamente. Mas isso não funciona. Sua saída foi "Kennedy, Fitzgerald, John, / out.", Uma solução parcial seria main(a,b)int**b;{--a&&printf("%s, ",b[a])&&main(a,b);}. É 2 bytes mais curto e garante que você não imprima o nome do programa, mas ainda usa vírgula entre cada nome.
Sigvaldm 25/05
3

Mathematica, 45 bytes

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

Economizou alguns bytes em relação à resposta da ngenisis, inserindo a entrada como uma lista de caracteres e não como uma string. Função pura que usa uma regra de substituição de padrão.

Mathematica, 49 bytes

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

Outra função pura pegando uma lista de caracteres como entrada e retornando uma lista de caracteres. Este acrescenta ","e " "à entrada e gira a lista de caracteres até o último espaço estar no final. (Portanto, a saída possui um espaço à direita, diferente da primeira função acima.)

Greg Martin
fonte
#/.{a__,s=" ",b:Except@s..}->{b,",",s,a}&é 4bytes mais curtos, mas descobri que isso não Excepté necessário para os padrões de string, poupando-me 12bytes.
Ngenisis
ah, ele escolhe automaticamente o mais longo xna sua resposta?
Greg Martin
Sim, a correspondência de padrões de cordas é gananciosa, mas a correspondência regular de padrões é preguiçosa.
Ngenisis
agradáveis <ondas de bandeira branca>
Greg Martin
3

C #, 76 72 bytes

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

Guardado 4 bytes com a ajuda de @KevinCruijssen

Versão antiga usando substrings para 76 bytes:

s=>s.Substring(s.LastIndexOf(' ')+1)+", "+s.Substring(0,s.LastIndexOf(' '));
TheLethalCoder
fonte
1
Pena que System.Text.RegularExpressions.Regexé tão longo em C # .. s=>new System.Text.RegularExpressions.Regex("(.+) (.+)").Replace(s,"$2, $1");é apenas um byte a mais.
Kevin Cruijssen
1
@KevinCruijssen verdade, mas eu posso usar o método estático em Regexsalvar 4 bytes
TheLethalCoder
3

Awk, 18 caracteres

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

Exemplo de execução:

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

Experimente online!

homem a trabalhar
fonte
2

Gelatina , 8 bytes

Ḳ©Ṫ”,⁶®K

Experimente online!

HyperNeutrino
fonte
Droga, Ninja e derrotado.
ATaco 24/05
@ATaco gg :) e esse é um grande ninja.
HyperNeutrino
1
(Eu estava jogando golfe, shhh)
ATaco
2

05AB1E , 9 bytes

#`',«.Áðý

Experimente online!

Explicação

#           # 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
fonte
Sim, eu provavelmente deveria fazer um comando join by space: p
Adnan
@Adnan: Seria bom ver como muitas vezes ele é usado :)
Emigna
2

Pitão , 11 bytes

jd.>c+z\,d1

Explicação:

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

Teste online!

Jim
fonte
2

PHP, 45 bytes

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

Experimente online!

Jörg Hülsermann
fonte
1
Por que ao \pL+invés de .+?
Kevin Cruijssen
@KevinCruijssen Você direita são a primeira parte da regex é ganancioso por isso não importa de usar .ou\pL
Jörg Hülsermann
2

MATLAB / oitava , 37 bytes

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

Experimente online!

Com base na resposta Retina do @ngenisis, também podemos jogar o jogo regex no Octave e no MATLAB, economizando alguns bytes em relação à minha resposta anterior.


Resposta antiga:

Vou deixar essa resposta aqui também, considerando que é uma maneira mais exclusiva de fazer isso em comparação com uma regex simples.

Oitava , 49 47 bytes

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

Antigo experimentá-lo online!

Uma função anônima para gerar a saída.

Basicamente, o código encontra primeiro o último espaço na string usando b=find(a==32)(end). Depois, pega a parte final da string (após o espaço) usando a(b+1:end), onde bestá a saída de encontrar o último espaço. Também leva o início da string com a(1:b-1), e concatena ambos junto com um ', 'no meio.

Eu já salvei alguns bytes vs o típico find(a==32,1,'last'). Não tenho certeza se há muito mais para economizar.

Tom Carpenter
fonte
2

Geléia , 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.

Experimente online!

Experimente todos os casos de teste.

ATaco
fonte
2

Python 3, 52 bytes

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

Muito simples, poderia usar a ajuda do golfe. Apenas coloca a última palavra na frente e junta-as a ",".

Caso de teste:

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

Java, 110 62 bytes

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

Método não estático.

-48 bytes graças a Kevin Cruijssen

HyperNeutrino
fonte
String c(String s){int i=s.lastIndexOf(' ');return s.substring(i+1)+", "+s.substring(0,i);}é mais curto ( 91 bytes ).
Kevin Cruijssen
E String d(String s){return s.replaceAll("(.+) (.+)","$2, $1");}é ainda mais curto ( 62 bytes ).
Kevin Cruijssen
@KevinCruijssen Oh caramba legal. Obrigado! Eu deveria aprender a usar regex melhor: P
HyperNeutrino
2

PHP , 62 59 bytes

-3 bytes, obrigado Jörg

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

Experimente online!

Solução antiga, 63 bytes

Não funciona se a pessoa tiver 3 nomes repetidos.

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

Experimente online

MIM
fonte
Você pode usar em $argnvez de$argv[1]
Jörg Hülsermann
2

Excel, 174 170 168 bytes

Economizou 2 bytes graças 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," ","")))))

Isso não é chique ou inteligente. É um método bastante básico. Parece que deve haver uma maneira mais curta com fórmulas de matriz, mas não consigo encontrar uma que funcione.

Engenheiro Toast
fonte
A solução funciona apenas para casos em que existem três nomes. Não lida com "Albert Einstein", por exemplo.
Wernisch
@Wernisch Thanks! Deve funcionar agora.
Engenheiro Toast
O espaço em branco à direita é permitido de acordo com a pergunta. Pense que você pode economizar 2 bytes, deixando de fora o -1na função ESQUERDA.
Wernisch
1

JS (ES6), 52 44 bytes

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

MATL , 10 bytes

44hYb1YSZc

Experimente online!

Explicação

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

Gema, 23 caracteres

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

A única coisa notável aqui é como o desafio conseguiu atingir a fraqueza da não cobiça dos padrões de Gema.

Exemplo de execução:

bash-4.4$ echo -n 'John Fitzgerald Kennedy' | gema '* =@append{s; *};\Z=,$s'
Kennedy, John Fitzgerald
homem a trabalhar
fonte