Kto ma przecinek na drugie imię?

18

Twoim wyzwaniem jest przyjęcie nazwy (łańcucha) jako danych wejściowych, takich jak

Albert Einstein

i wyjście:

Einstein, Albert

Pseudo kod:

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

Więcej przypadków testowych:

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

Zasady

  • Dane wejściowe zawsze będą pasować do wyrażenia regularnego ^([A-Z][a-z]+ )+([A-Z][a-z]+)$.
  • Nie musisz radzić sobie z dziwnymi nazwami , nawet jeśli dane wyjściowe są technicznie niepoprawne, tutaj jest w porządku.
  • Końcowe białe znaki / nowa linia są w porządku.
  • Jakieś pytania? Komentarz poniżej!
programmer5000
źródło
Czy dozwolone są spacje końcowe?
Wartość tuszu
Zamknęłam za dupe bo rozwiązania mogą dość dużo siply zastąpić lez ,i masz na to pytanie
Downgoat
2
@Downgoat To wyzwanie określa dwa słowa, podczas gdy rozwiązania tego muszą działać na dowolnie wiele słów. O ile mogę powiedzieć, o odpowiedziach z linkami TIO, tylko rozwiązanie Poważnie daje prawidłową odpowiedź na to pytanie zastępując leje ,.
ngenisis
7
@Downgoat, który ma -4. Przynajmniej zamknij to jako duplikat tego.
Stephen
1
Czy spacje końcowe są w porządku?
Tom Carpenter

Odpowiedzi:

10

05AB1E , 7 bajtów

Kod:

',ì#Áðý

Wykorzystuje kodowanie 05AB1E . Wypróbuj online!

Wyjaśnienie:

',ì         # Prepend the input to ","
   #        # Split on spaces
    Á       # Rotate every element one position to the right (wrapping)
     ðý     # Join the array by spaces
Adnan
źródło
1
Przygotuj! Wiedziałem, że musi istnieć sposób na zrobienie tego w formie listy.
Emigna
9

JavaScript (ES6), 34 bajty

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

Próbny:

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

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

żyr
źródło
8

Retina , 19 17 16 bajtów

Edycja: Podziękowania dla Riker za zapisanie 3 bajtów

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

Wypróbuj online!

ngenisis
źródło
1
wstrzymaj się, (.+)działa również dla obu.
Rɪᴋᴇʀ
Nie rozumiem, dlaczego \w
używałeś
1
@ thehelylygusti Jestem bardziej zaznajomiony z dopasowywaniem wzorców w Mathematica, która używa leniwego dopasowywania zamiast chciwości.
ngenisis
7

Galaretka , 7 bajtów

;”,Ḳṙ-K

Wypróbuj online!

Nie znam się zbyt dobrze na Jelly, ale czytając inne odpowiedzi, wyglądało to tak, jakby nie korzystali z optymalnego algorytmu ... więc oto:

Wyjaśnienie

;”,Ḳṙ-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
Lew
źródło
7

Vim, 10 bajtów / naciśnięć klawiszy

v$F dA, <esc>p

Wypróbuj online!

DJMcMayhem
źródło
Fajny, ale starałem się go uruchomić, <esc>nie pojawia się w twoim kodzie. Zawiadomienie dla innych, którzy chcą spróbować: Zakłada się, że nazwa jest zapisana w edytorze i że aktualnie znajdujesz się na początku pliku w trybie normalnym.
sigvaldm
7

V / vim, 9 8 bajtów

$bD0Pa, 

Wypróbuj online!

Zapisano jeden bajt dzięki

Zauważ, że występuje spacja końcowa. Pozostawia końcowe miejsce, które jest dozwolone zgodnie z regułami.

Wyjaśnienie:

$       " 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
źródło
Niezłe! Dobrym pomysłem jest umieszczenie trybu wstawiania na końcu, aby uniknąć potrzeby <esc>. Możesz zapisać jeden bajt, wykonując $bDzamiast $diw. :)
DJMcMayhem
Dzięki. $bDnie obsługuje nazw jednoznakowych, zapytałem OP, czy jest to dozwolone.
Kevin
Wygląda na to, że tak, więc aktualizacja.
Kevin
6

Mathematica, 52 40 bajtów

StringReplace[x__~~" "~~y__:>y<>", "<>x]
ngenisis
źródło
5

C, 45 bajtów

EDYCJA: Właśnie zauważyłem, że wejście może mieć więcej niż dwa słowa. Zostawię tak, jak jest, z notatką, że to działa tylko na dwa słowa.

EDYCJA: usunięta \n. Dodaj 2 bajty, jeśli uznasz to za konieczne.

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

Kompiluje się z gcc name.cGCC 6.3.1. Zignoruj ​​ostrzeżenia. Stosowanie:

$./a.out Albert Einstein
Einstein, Albert

Nadużycie języka:

  • Niejawna typ zwracany intz maini nic nie wrócił.
  • Domniemana deklaracja printf. GCC i tak to uwzględni.
  • Zły typ b. To nie ma znaczenia%s

Dzięki @ Khaled.K za wskazówki dotyczące używania main(a,b)int**b;zamiast main(int a, int **b).

Sigvaldm
źródło
Miły pierwszy golf, witamy na stronie, również main(a,**b){printf("%s, %s",b[2],b[1]);}ma 40 bajtów
Khaled.K
Dzięki :) Właściwie to pomyślałem o całkowitym pominięciu typów, ale z jakiegoś powodu nie skompiluje się.
sigvaldm
1
To działamain(a,b)int**b;{printf("%s, %s\n",b[2],b[1]);}
Khaled.K
4

sed, 19 + 1 dla -E = 20 bajtów

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

Należy użyć opcji -r (GNU) lub -E (BSD, najnowsze GNU), aby uniknąć konieczności ucieczki z nawiasu grupującego.

Jeśli napisane w wierszu poleceń, muszą być ujęte w cudzysłowy, aby uniknąć parsowania przez powłokę jako wielu tokenów:

sed -E 's/(.*) (.*)/\2, \1/'
Aaron
źródło
4

C, 68 bajtów

Mam nadzieję, że nie jest źle dodawać kolejny post, ale oto nieco inne rozwiązanie niż moje wcześniej opublikowane rozwiązanie C. Ten akceptuje dowolną liczbę nazw.

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

Kompiluj z gcc name.c(GCC 6.3.1) i ignoruj ​​ostrzeżenia. Stosowanie:

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

Dzięki @ Khaled.K za wskazówki dotyczące main(a,b)int**b;

Dzięki za wskazówkę dotyczącą pętli for do @Alkano.

Sigvaldm
źródło
1
możesz zyskać 2 bajty, używając for zamiast zamiast na chwilę main(a,b)int**b;{for(printf("%s,",b[--a]);++b,--a;printf(" %s",*b));}
Alkano
To brzmi szalenie, ale możesz to zrobićmain(a,b)int**b;{a&&printf("%s,"b[a-1])&&main(a-1,b);}
Khaled.K,
Bardzo fajne sztuczki :) Nigdy nie myślałem o nazywaniu main rekurencyjnym. Ale to nie do końca działa. Jego wynikiem było „Kennedy, Fitzgerald, John,. / A.out”, Częściowe rozwiązanie byłoby main(a,b)int**b;{--a&&printf("%s, ",b[a])&&main(a,b);}. Jest o 2 bajty krótszy i zapewnia, że ​​nie drukujesz nazwy programu, ale nadal używa przecinków między każdą nazwą.
sigvaldm
3

Mathematica, 45 bajtów

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

Zapisano kilka bajtów nad odpowiedzią ngenisis, przyjmując dane wejściowe jako listę znaków, a nie ciąg znaków. Czysta funkcja korzystająca z reguły zastępowania wzorców.

Mathematica, 49 bajtów

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

Kolejna czysta funkcja pobierająca listę znaków jako dane wejściowe i zwracająca listę znaków. Ten dołącza ","i " "do wejścia, a następnie obraca listę znaków, aż ostatnia spacja znajdzie się na końcu. (W ten sposób dane wyjściowe mają spację końcową, w przeciwieństwie do pierwszej funkcji powyżej.)

Greg Martin
źródło
#/.{a__,s=" ",b:Except@s..}->{b,",",s,a}&jest 4bajtów krótszy, ale okazało się, że nie Exceptjest potrzebny do wzorców łańcuchowych, co oszczędza mi 12bajtów.
ngenisis
ah, czy automatycznie wybiera najdłuższą xodpowiedź?
Greg Martin
Tak, dopasowanie wzorca łańcucha jest zachłanne, ale regularne dopasowanie wzorca jest leniwe.
ngenisis
nice <fale biała flaga>
Greg Martin
3

DO#, 76 72 bajtów

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

Zaoszczędź 4 bajty przy pomocy @KevinCruijssen

Stara wersja wykorzystująca podciągi dla 76 bajtów:

s=>s.Substring(s.LastIndexOf(' ')+1)+", "+s.Substring(0,s.LastIndexOf(' '));
TheLethalCoder
źródło
1
Szkoda, że System.Text.RegularExpressions.Regexjest tak cholernie długo w C # .. s=>new System.Text.RegularExpressions.Regex("(.+) (.+)").Replace(s,"$2, $1");to tylko jeden bajt więcej.
Kevin Cruijssen
1
@KevinCruijssen Prawda, ale mogę użyć metody statycznej, Regexaby zaoszczędzić 4 bajty
TheLethalCoder
3

Awk, 18 znaków

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

Przykładowy przebieg:

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

Wypróbuj online!

człowiek w pracy
źródło
2

Galaretka , 8 bajtów

Ḳ©Ṫ”,⁶®K

Wypróbuj online!

HyperNeutrino
źródło
Cholera, Ninja i rozegrany.
ATaco
@ATaco gg :) i to całkiem duży ninja.
HyperNeutrino
1
(Grałem w golfa,
ćśśśś
2

05AB1E , 9 bajtów

#`',«.Áðý

Wypróbuj online!

Wyjaśnienie

#           # 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
źródło
Tak, prawdopodobnie powinienem wykonać połączenie za pomocą spacji: p
Adnan
@Adnan: Byłoby miło zobaczyć, jak często jest używany :)
Emigna
2

Pyth , 11 bajtów

jd.>c+z\,d1

Wyjaśnienie:

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

Przetestuj online!

Jim
źródło
2

PHP, 45 Bytes

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

Try it online!

Jörg Hülsermann
źródło
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
źródło
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
źródło
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
źródło
2

Java, 110 62 bytes

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

Non-static method.

-48 bytes thanks to Kevin Cruijssen

HyperNeutrino
źródło
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
źródło
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
źródło
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
źródło
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
źródło
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
źródło