Chi ha una virgola per un secondo nome?


18

La tua sfida è quella di prendere un nome (stringa) come input, come

Albert Einstein

e uscita:

Einstein, Albert

pseudocodice:

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

Altri casi di test:

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

Regole

  • L'input corrisponderà sempre alla regex ^([A-Z][a-z]+ )+([A-Z][a-z]+)$.
  • Non è necessario gestire nomi strani , anche se l'output è tecnicamente errato, qui va bene.
  • Gli spazi bianchi / newline finali sono OK.
  • Qualsiasi domanda? Commenta sotto!

Sono consentiti spazi finali?
Value Ink

Ho chiuso come duplicato perché le soluzioni possono essere praticamente sostituite lecon siply ,e hai questa domanda
Downgoat,

2
@Downgoat Quella sfida specifica due parole, mentre le soluzioni devono funzionare arbitrariamente per molte parole. Per quanto posso dire, delle risposte con collegamenti TIO, solo il Scherzi soluzione dà la risposta corretta per questa domanda Sostituendo lecon ,.
ngenisi,

7
@Downgoat che uno ha -4. Almeno chiudilo come un inganno.
Stephen,

1
Gli spazi finali sono ok?
Tom Carpenter,

Risposte:


10

05AB1E , 7 byte

Codice:

',ì#Áðý

Utilizza la codifica 05AB1E . Provalo online!

Spiegazione:

',ì         # Prepend the input to ","
   #        # Split on spaces
    Á       # Rotate every element one position to the right (wrapping)
     ðý     # Join the array by spaces

1
Anteporre! Sapevo che doveva esserci un modo per farlo in lista.
Emigna,

9

JavaScript (ES6), 34 byte

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


8

Retina , 19 17 16 byte

Modifica: grazie a Riker per aver salvato 3 byte

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

Provalo online!


1
resisti, (.+)funziona anche per entrambi.
Rɪᴋᴇʀ

Non capisco perché stavi usando \win primo luogo
theonlygusti

1
@theonlygusti Ho più familiarità con il pattern matching in Mathematica, che usa un abbinamento pigro piuttosto che avido.
ngenisi,

7

Gelatina , 7 byte

;”,Ḳṙ-K

Provalo online!

Non conosco molto bene Jelly, ma leggendo altre risposte sembra che non abbiano usato un algoritmo ottimale ... quindi eccolo:

Spiegazione

;”,Ḳṙ-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 byte / sequenze di tasti

v$F dA, <esc>p

Provalo online!


Bello, ma ho faticato a farlo funzionare, <esc>non compare nel tuo codice. Per avviso agli altri che vogliono provare: questo presuppone che il nome sia scritto nell'editor e che tu sia attualmente all'inizio del file in modalità normale.
sigvaldm,

7

V / vim, 9 8 byte

$bD0Pa, 

Provalo online!

Salvato un byte grazie a

Nota che c'è un carattere spazio finale. Lascia uno spazio finale, consentito dalle regole.

Spiegazione:

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

Ben fatto! Buona idea mettere la modalità di inserimento alla fine per evitare di averne bisogno <esc>. È possibile salvare un byte facendo $bDinvece di $diw. :)
DJMcMayhem

Grazie. $bDnon gestisce i nomi di un carattere però, ho chiesto a OP se è permesso.
Kevin,

Sembra che sia così, quindi l'aggiornamento.
Kevin,


6

Mathematica, 52 40 byte

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


5

C, 45 byte

EDIT: ho appena notato il requisito per l'input che potrebbe contenere più di due parole. Lo lascerò così com'è con una nota che funziona solo per due parole.

EDIT: rimosso \n. Aggiungi 2 byte se lo ritieni necessario.

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

Compilare con gcc name.c, GCC 6.3.1. Ignora gli avvisi. Uso:

$./a.out Albert Einstein
Einstein, Albert

Abuso di lingua:

  • Tipo intdi ritorno implicito di maine niente restituito.
  • Dichiarazione implicita di printf. GCC lo includerà comunque.
  • Tipo sbagliato di b. Non importa%s

Grazie a @ Khaled.K per i suggerimenti sull'utilizzo main(a,b)int**b;anziché main(int a, int **b).


Bel primo golf, benvenuto nel sito web, anche main(a,**b){printf("%s, %s",b[2],b[1]);}40 byte
Khaled.K

Grazie :) In realtà ho pensato di omettere completamente i tipi, ma per qualche motivo non si sarebbe compilato.
sigvaldm,

1
Funziona cosìmain(a,b)int**b;{printf("%s, %s\n",b[2],b[1]);}
Khaled.K,


4

sed, 19 + 1 per -E = 20 byte

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

È necessario utilizzare -r (GNU) o -E (BSD, GNU recenti) per evitare di dover sfuggire alla parentesi di raggruppamento.

Se scritto sulla riga di comando, deve essere racchiuso tra virgolette per evitare di essere analizzato come token multipli dalla shell:

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

4

C, 68 byte

Spero non sia sbagliato aggiungere un altro post, ma ecco una soluzione leggermente diversa dalla mia soluzione C precedentemente pubblicata. Questo accetta un numero qualsiasi di nomi.

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

Compilare con gcc name.c(GCC 6.3.1) e ignorare gli avvisi. Uso:

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

Grazie a @ Khaled.K per i suggerimenti su main(a,b)int**b;

Grazie per il suggerimento sul ciclo for a @Alkano.


1
puoi guadagnare 2 byte, usando for invece di while main(a,b)int**b;{for(printf("%s,",b[--a]);++b,--a;printf(" %s",*b));}
Alkano

Sembra folle, ma puoi farlomain(a,b)int**b;{a&&printf("%s,"b[a-1])&&main(a-1,b);}
Khaled.K,

Trucchi molto belli :) Non ho mai pensato di chiamare ricorsivamente main. Ma non funziona del tutto. Il risultato fu "Kennedy, Fitzgerald, John,. / A.out," Una soluzione parziale sarebbe main(a,b)int**b;{--a&&printf("%s, ",b[a])&&main(a,b);}. È più breve di 2 byte e garantisce di non stampare il nome del programma, ma utilizza comunque la virgola tra ciascun nome.
sigvaldm,

3

Mathematica, 45 byte

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

Ho salvato qualche byte sulla risposta di ngenisis prendendo l'input come un elenco di caratteri anziché come una stringa. Funzione pura che utilizza una regola di sostituzione del modello.

Mathematica, 49 byte

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

Un'altra funzione pura che prende un elenco di caratteri come input e restituisce un elenco di caratteri. Questo aggiunge ","e " "all'input e quindi ruota l'elenco di caratteri fino a quando l'ultimo spazio è alla fine. (Quindi l'output ha uno spazio finale, a differenza della prima funzione sopra.)


#/.{a__,s=" ",b:Except@s..}->{b,",",s,a}&i 4byte sono più brevi, ma ho scoperto che Exceptnon è necessario per gli schemi di stringhe, salvandomi 12byte.
ngenisi,

ah, sceglie automaticamente il più lungo xnella tua risposta?
Greg Martin,

Sì, la corrispondenza del motivo a corde è avida, ma la corrispondenza regolare del motivo è pigra.
ngenisi,

bello <onde bandiera bianca>
Greg Martin

3

C #, 76 72 byte

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

Salvato 4 byte con l'aiuto di @KevinCruijssen

Vecchia versione che utilizza sottostringhe per 76 byte:

s=>s.Substring(s.LastIndexOf(' ')+1)+", "+s.Substring(0,s.LastIndexOf(' '));

1
Peccato che System.Text.RegularExpressions.Regexsia così dannatamente lungo in C # .. s=>new System.Text.RegularExpressions.Regex("(.+) (.+)").Replace(s,"$2, $1");è solo un byte in più.
Kevin Cruijssen,

1
@KevinCruijssen Vero ma posso usare il metodo statico Regexper salvare 4 byte
TheLethalCoder

3

Awk, 18 personaggi

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

Esecuzione di esempio:

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

Provalo online!



2

05AB1E , 9 byte

#`',«.Áðý

Provalo online!

Spiegazione

#           # split input on spaces
 `          # push each name separately to stack
  ',«       # concatenate a comma to the last name
     .Á     # rotate stack right
       ðý   # join stack by spaces

Sì, probabilmente dovrei unirmi al comando spaziale: p
Adnan,

@Adnan: Sarebbe bello vedere quanto spesso viene usato :)
Emigna

2

Pyth , 11 byte

jd.>c+z\,d1

Spiegazione:

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

Provalo online!



2

MATLAB / Octave , 37 byte

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

Provalo online!

Basato sulla risposta Retina di @ngenisis, possiamo anche giocare al gioco regex sia in Octave che in MATLAB, risparmiando un discreto numero di byte rispetto alla mia risposta precedente.


Vecchia risposta:

Lascio questa risposta anche qui considerando che è un modo più unico di farlo rispetto ad una semplice regex.

Ottava , 49 47 byte

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

Vecchio provalo online!

Una funzione anonima per generare l'output.

Fondamentalmente il codice trova prima l'ultimo spazio nella stringa usando b=find(a==32)(end). Quindi prende la parte finale della stringa (dopo lo spazio) usando a(b+1:end), dove bè l'output di trovare l'ultimo spazio. Prende anche l'inizio della stringa con a(1:b-1)e concatena entrambi insieme con una via ', 'di mezzo.

Ho già salvato alcuni byte rispetto al tipico find(a==32,1,'last'). Non sono sicuro che ci sia molto altro da salvare.


2

Gelatina , 9 byte

ḲµṪ;⁾, ;K

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

Provalo online!

Prova tutti i casi di test.


2

Python 3, 52 byte

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

Molto semplice, potrebbe usare l'aiuto del golf. Mette solo l'ultima parola in primo piano e li unisce a ",".

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 byte

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

Metodo non statico.

-48 byte grazie a Kevin Cruijssen


String c(String s){int i=s.lastIndexOf(' ');return s.substring(i+1)+", "+s.substring(0,i);}è più corto ( 91 byte ).
Kevin Cruijssen,

Ed String d(String s){return s.replaceAll("(.+) (.+)","$2, $1");}è ancora più breve ( 62 byte ).
Kevin Cruijssen,

@KevinCruijssen Oh cavolo carino. Grazie! Dovrei imparare ad usare meglio regex: P
HyperNeutrino,

2

PHP , 62 59 byte

-3 byte, grazie Jörg

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

Provalo online!

Vecchia soluzione, 63 byte

Non funziona se la persona ha 3 nomi ricorrenti.

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

Provalo online


Puoi usare $argninvece di$argv[1]
Jörg Hülsermann

2

Excel, 174 170 168 byte

Salvato 2 byte grazie 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," ","")))))

Questo non è elegante o intelligente. È un metodo abbastanza semplice. Sembra che ci dovrebbe essere un modo più breve con le formule di array ma non riesco a trovarne uno che funzioni.


La soluzione funziona solo per i casi in cui ci sono tre nomi. Ad esempio, non gestisce "Albert Einstein".
Wernisch,

@Wernisch Grazie! Dovrebbe funzionare ora.
Ingegnere Toast,

Lo spazio bianco finale è consentito in base alla domanda. Pensi di poter salvare 2 byte tralasciando -1la funzione LEFT.
Wernisch,


1

MATL , 10 byte

44hYb1YSZc

Provalo online!

Spiegazione

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 personaggi

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

L'unica cosa notevole qui è come la sfida è riuscita a colpire la debolezza della non avidità dei modelli Gema.

Esecuzione di esempio:

bash-4.4$ echo -n 'John Fitzgerald Kennedy' | gema '* =@append{s; *};\Z=,$s'
Kennedy, John Fitzgerald
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.