У кого є кома для прізвища?


18

Ваше завдання полягає в тому, щоб взяти ім’я (рядок) як вхідне, як

Albert Einstein

і вихід:

Einstein, Albert

Псевдокод:

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

Більше тестових випадків:

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

Правила

  • Вхід завжди відповідатиме регулярним виразом ^([A-Z][a-z]+ )+([A-Z][a-z]+)$.
  • Вам не потрібно впоратися дивні імена , навіть якщо висновок технічно неправильний, тут добре.
  • Пробіл пробілів / новий рядок у порядку.
  • Які-небудь питання? Прокоментуйте нижче!

Чи дозволені пробіли?
Значення чорнила

Я закрив , як простак , тому що рішення можуть в значній мірі siply замінити leз ,і у вас є це питання
Downgoat

2
@Downgoat Цей виклик вказує два слова, тоді як рішення цього завдання повинні працювати для довільно багатьох слів. Наскільки я можу судити, відповіді з TiO посилання, тільки серйозно рішення дає правильну відповідь на це питання підставляючи leз ,.
ngenisis

7
@Downgoat, що має -4. Принаймні, близько до цього, як про це.
Стівен

1
Чи добре проміжки проміжків?
Том Карпентер

Відповіді:


10

05AB1E , 7 байт

Код:

',ì#Áðý

Використовує кодування 05AB1E . Спробуйте в Інтернеті!

Пояснення:

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

1
Придбати! Я знав, що повинен бути спосіб зробити це у списку.
Емінья

9

JavaScript (ES6), 34 байти

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

Демонстрація:

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

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


8

Сітківка , 19 17 16 байт

Редагувати: Дякую Рікер за збереження 3 байтів

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

Спробуйте в Інтернеті!


1
тримайся, (.+)теж працює для обох.
Rɪᴋᴇʀ

Я не розумію, чому ви користувалися \wв першу чергу
theonlygusti

1
@theonlygusti Мені більше знайоме відповідність шаблонів у Mathematica, яка використовує ледачу відповідність, а не жадібну.
ngenisis

7

Желе , 7 байт

;”,Ḳṙ-K

Спробуйте в Інтернеті!

Я не знаю Jelly дуже добре, але читаючи інші відповіді, здавалося, що вони не використовують оптимальний алгоритм ... так ось це:

Пояснення

;”,Ḳṙ-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 байт / натискання клавіш

v$F dA, <esc>p

Спробуйте в Інтернеті!


Хороший, але я намагався його працювати, <esc>не відображається у вашому коді. Для повідомлення іншим, хто хоче спробувати: Це передбачає, що ім'я записано в редакторі і що ви зараз перебуваєте на початку файлу в звичайному режимі.
sigvaldm

7

V / vim, 9 8 байт

$bD0Pa, 

Спробуйте в Інтернеті!

Збережено один байт завдяки

Зверніть увагу, є символ пробілу. Залишається простір, який дозволено згідно з правилами.

Пояснення:

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

Хороший! Добре подумайте, щоб поставити режим вставки в кінці, щоб уникнути необхідності <esc>. Ви можете зберегти один байт, виконуючи $bDзамість цього $diw. :)
DJMcMayhem

Спасибі. $bDХоча не обробляє одноіменні імена, я запитав ОП, чи це дозволено.
Кевін

Схоже, це так, тож оновлення.
Кевін




5

C, 45 байт

EDIT: Я щойно помітив вимогу до вводу, який, можливо, має більше двох слів. Я залишу це як є із зауваженням, що це працює лише на два слова.

EDIT: видалено \n. Додайте 2 байти, якщо вважаєте за потрібне.

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

Компілюється з gcc name.c, GCC 6.3.1. Ігноруйте попередження. Використання:

$./a.out Albert Einstein
Einstein, Albert

Зловживання мовою:

  • Неявний тип повернення intзmain і нічого не повертається.
  • Неявна заява про printf . GCC все одно включить його.
  • Неправильний тип b. Не має значення%s

Дякуємо @ Khaled.K за поради щодо використання, main(a,b)int**b;а не main(int a, int **b).


Перший хороший гольф, ласкаво просимо на веб-сайті, також main(a,**b){printf("%s, %s",b[2],b[1]);}- 40 байт
Khaled.K

Дякую :) Насправді я думав про те, щоб повністю пропустити типи, але чомусь це не складеться.
sigvaldm

1
Це працюєmain(a,b)int**b;{printf("%s, %s\n",b[2],b[1]);}
Халед.К


4

sed, 19 + 1 для -E = 20 байт

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

Потрібно використовувати -r (GNU) або -E (BSD, останні GNU), щоб уникнути необхідності уникати угрупованих дужок.

Якщо це написано в командному рядку, його потрібно укласти в лапки, щоб не розбирати оболонку як декілька лексем:

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

4

C, 68 байт

Сподіваюся, що це не помилково додати ще одну посаду, але ось дещо інше рішення, ніж моє раніше розміщене рішення C. Цей приймає будь-яку кількість імен.

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

Компілюйте з gcc name.c(GCC 6.3.1) і ігноруйте попередження. Використання:

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

Дякуємо @ Khaled.K за поради щодо main(a,b)int**b;

Дякуємо за підказку щодо циклу for для @Alkano.


1
ви можете отримати 2 байти, використовуючи замість поки main(a,b)int**b;{for(printf("%s,",b[--a]);++b,--a;printf(" %s",*b));}
Алкано

Це звучить божевільно, але ви можете це зробитиmain(a,b)int**b;{a&&printf("%s,"b[a-1])&&main(a-1,b);}
Khaled.K

Дуже приємні трюки :) Я ніколи не замислювався над тим, щоб називати головне рекурсивно. Але це не зовсім працює. Його вихід був "Kennedy, Fitzgerald, John,. / A.out", Часткове рішення було б main(a,b)int**b;{--a&&printf("%s, ",b[a])&&main(a,b);}. Це на 2 байти коротше, і це означає, що ви не друкуєте назву програми, але вона все ще використовує кому між кожним іменем.
sigvaldm

3

Математика, 45 байт

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

Збережено кілька байт над відповіддю ngenisis взявши введення як список символів, а не як рядок. Чиста функція, яка використовує правило заміни шаблону.

Математика, 49 байт

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

Ще одна чиста функція, що приймає список символів як вхідний і повертає список символів. Цей додається ","і " "до вводу, а потім обертає список символів до останнього пробілу в кінці. (Таким чином, на виході є простір, що відкладається, на відміну від першої функції вище.)


#/.{a__,s=" ",b:Except@s..}->{b,",",s,a}&є 4байтами коротшими, але я з'ясував, що значення Exceptрядкових шаблонів не потрібне, економивши мені 12байти.
ngenisis

ах, це автоматично вибирає найдовший xу вашій відповіді?
Грег Мартін

Так, узгодження рядкових шаблонів жадібне, але регулярне узгодження шаблонів ліниво
ngenisis

приємно <хвилі білого прапора>
Грег Мартін

3

C #, 76 72 байти

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

Збережено 4 байти за допомогою @KevinCruijssen

Стара версія з використанням підрядків на 76 байт:

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

1
Шкода System.Text.RegularExpressions.Regex, так чорт довго в C # .. s=>new System.Text.RegularExpressions.Regex("(.+) (.+)").Replace(s,"$2, $1");- це лише на один байт більше.
Кевін Круїссен

1
@KevinCruijssen Щоправда, але я можу використовувати статичний метод, Regexщоб зберегти 4 байти
TheLethalCoder




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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.