pwaS eht tirsf dna tasl setterl fo hace dorw


30

Або "Обміняйте першу та останню літери кожного слова"

Ваше завдання полягає в тому, щоб, задавши рядок алфавітних символів ASCII, а також один інший символ, який слід використовувати як роздільник (для розділення кожного слова), поміняти місцями першу та останню літери кожного слова. Якщо є однозначне слово, залиште його в спокої.

У прикладах / тестових скриньках використовуються малі літери та пробіл як роздільник.

Вам не потрібно обробляти розділові знаки; всі входи будуть складатися лише з літер a - z, розділених роздільником, і все однорідний регістр.

Наприклад, із рядком "привіт світ":

Input string: "hello world"
Identify each word: "[hello] [world]"
Identify the first and last letters of each word: "[[h]ell[o]] [[w]orl[d]]"
Swap the first letters of each word: "[[o]ell[h]] [[d]orl[w]]"
Final string: "oellh dorlw"

ПРИМІТКА. Розмежувач не потрібно вводити окремо. Розмежувач - це просто символ, який використовується для розділення слів. Це може бути що завгодно. Я хотів залишити варіанти відкритими для творчих гольфістів, тому не хотів обмежувати це лише просторами або новими рядками. Розмежувач - це просто символ, який розділяє слова у вхідному рядку.

Тестові приклади:

"swap the first and last letters of each word" -> "pwas eht tirsf dna tasl setterl fo hace dorw"
"hello world" -> "oellh dorlw"
"test cases" -> "test sasec"
"programming puzzles and code golf" -> "grogramminp suzzlep dna eodc folg"
"in a green meadow" -> "ni a nreeg weadom"
"yay racecar" -> "yay racecar"

3
Як слід ставитися до пунктуації? Hello, world!стає ,elloH !orldw(міняючи розділові знаки як літеру) чи oellH, dorlw!(тримаючи розділові знаки на місці)?
Феліпе Олейник

3
@PhelypeOleinik Не потрібно обробляти розділові знаки; всі вхідні дані будуть складатися лише з літер від a до z, і всі однакові регістри.
Товариш SparklePony

4
Другий абзац читає, як і один інший символ, який слід використовувати як роздільник, а четвертий - розділений пробілами . Який це?
Адам

@ Adám Будь-який не алфавітний символ. Я відредагую, щоб уточнити.
Товариш SparklePony

1
@BenjaminUrquhart Так. Ви можете взяти введення як аргумент функції, якщо ви хочете.
Товариш SparklePony

Відповіді:


59

TeX, 216 байт (4 рядки, 54 символи в кожному)

Оскільки мова не йде про кількість байтів, а про якість виводу набору :-)

{\let~\catcode~`A13 \defA#1{~`#113\gdef}AGG#1{~`#1 13%
\global\let}GFF\elseGHH\fiAQQ{Q}AII{\ifxQ}AEE#1#2#3|{%
I#3#2#1FE{#1#2}#3|H}ADD#1#2|{I#1FE{}#1#2|H}ACC#1#2|{D%
#2Q|#1 }ABBH#1 {HI#1FC#1|BH}\gdef\S#1{\iftrueBH#1 Q }}

Спробуйте в Інтернеті! (Наверху; не впевнений, як це працює)

Повний тестовий файл:

{\let~\catcode~`A13 \defA#1{~`#113\gdef}AGG#1{~`#1 13%
\global\let}GFF\elseGHH\fiAQQ{Q}AII{\ifxQ}AEE#1#2#3|{%
I#3#2#1FE{#1#2}#3|H}ADD#1#2|{I#1FE{}#1#2|H}ACC#1#2|{D%
#2Q|#1 }ABBH#1 {HI#1FC#1|BH}\gdef\S#1{\iftrueBH#1 Q }}

\S{swap the a first and last letters of each word}

pwas eht a tirsf dna tasl setterl fo hace dorw

\S{SWAP THE A FIRST AND LAST LETTERS OF EACH WORD}

\bye

Вихід:

enter image description here


Для LaTeX вам просто потрібна плита котла:

\documentclass{article}
\begin{document}

{\let~\catcode~`A13 \defA#1{~`#113\gdef}AGG#1{~`#1 13%
\global\let}GFF\elseGHH\fiAQQ{Q}AII{\ifxQ}AEE#1#2#3|{%
I#3#2#1FE{#1#2}#3|H}ADD#1#2|{I#1FE{}#1#2|H}ACC#1#2|{D%
#2Q|#1 }ABBH#1 {HI#1FC#1|BH}\gdef\S#1{\iftrueBH#1 Q }}

\S{swap the a first and last letters of each word}

pwas eht a tirsf dna tasl setterl fo hace dorw

\S{SWAP THE A FIRST AND LAST LETTERS OF EACH WORD}

\end{document}

Пояснення

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

Для (не дуже) абсолютних початківців TeX

  • По-перше, і найважливіший пункт цього списку: код не повинен бути у формі прямокутника, навіть якщо поп-культура може привести вас до цього .

  • TeX - мова розширення макросу. Ви можете, наприклад, визначити, \def\sayhello#1{Hello, #1!}а потім написати, \sayhello{Code Golfists}щоб TeX надрукував Hello, Code Golfists!. Це називається "неозначений макрос", і щоб подати його перший (і єдиний, у цьому випадку) параметр, ви вкладете його в дужки. TeX видаляє ці дужки, коли макрос захоплює аргумент. Ви можете використовувати до 9 параметрів: \def\say#1#2{#1, #2!}тоді \say{Good news}{everyone}.

  • Аналог неделімітованій макросів, що ні дивно, роздільники з них :) Ви можете зробити попереднє визначення трохи більше семантичним : \def\say #1 to #2.{#1, #2!}. У цьому випадку за параметрами слідує так званий текст параметра . Такий параметр тексту розмежовує аргумент макросу ( #1розмежований ␣to␣, пробілами включено і #2розмежовано на .). Після цього визначення ви можете написати \say Good news to everyone., яке розшириться до Good news, everyone!. Приємно, чи не так? :) Однак обмежений аргумент - це (цитуючи TeXbook ) "найкоротшу (можливо, порожню) послідовність лексем з правильно вкладеними {...}групами, за якими вводиться цей конкретний список жетонів, що не мають параметрів". Це означає, що розширення\say Let's go to the mall to Martinвиробить дивне речення. В цьому випадку вам потрібно «приховати» перший ␣to␣з {...}: \say {Let's go to the mall} to Martin.

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

    • catcode 11 , який визначає лексеми, які можуть складати контрольну послідовність (шикарне ім'я для макросу). За замовчуванням усі літери [a-zA-Z] є кодовим кодом 11, тому я можу писати \hello, що є однією єдиною керуючою послідовністю, тоді \he11oяк керуюча послідовність \heз двома символами 1, а потім літера o, тому що 1це не кодовий код 11. Якщо я зробив \catcode`1=11, з цього моменту \he11oбуде одна контрольна послідовність. Важливим є те, що кодові коди встановлюються, коли TeX вперше бачить персонажа під рукою, і такий кодовий код заморожений ... ЗАВЖДИ! (можуть застосовуватися умови)

    • кодовий код 12 , який є більшістю інших символів, таких як 0"!@*(?,.-+/тощо. Вони є найменш особливим типом кодового коду, оскільки вони служать лише для написання матеріалів на папері. Але ей, хто використовує TeX для написання?!? (знову ж, можуть застосовуватися умови)

    • catcode 13 , що пекло :) Дійсно. Перестань читати і йди робити щось із свого життя. Ви не хочете знати, що таке кодовий код 13. Коли-небудь чули про п’ятницю, 13-го? Здогадайтесь, звідки вона отримала свою назву! Продовжуйте на власний ризик! Символ коду 13, який ще називають "активним" символом, вже не просто символ, це сам макрос! Ви можете визначити його з параметрами та розгорнути на щось подібне, що ми бачили вище. Після того як \catcode`e=13ви думаєте, що можете зробити \def e{I am the letter e!}, АЛЕ ТИ. КАННОТ! eце вже не лист, так \defце не \defви знаєте, це \d e f! О, виберіть інший лист, який ви говорите? Гаразд! \catcode`R=13 \def R{I am an ARRR!}. Дуже добре, Джиммі, спробуй! Я смію це зробити і написати Rсвій код! Ось що таке кодовий код 13. Я - КЛАМ! Перейдемо далі.

  • Гаразд, зараз до групування. Це досить просто. Незалежно від призначення ( \defце операція з присвоєнням, \let(ми ввійдемо в неї) - це інша), яка виконується в групі, відновлюються до того, що вони були до початку цієї групи, якщо це призначення не є глобальним. Існує кілька способів запустити групи, один з них - з кодовим кодом 1 і 2 символи (о, знову ж таки коди). За замовчуванням {це кодовий код 1, або початкова група, і }це кодовий код 2, або кінцева група. Приклад: \def\a{1} \a{\def\a{2} \a} \aЦе відбитки 1 2 1. Поза групою \aбула 1, потім всередині була перероблена 2, і коли група закінчилася, вона була відновлена 1.

  • \letОперація інша операція присвоювання , як \def, а по- іншому. З \defви визначити макроси , які будуть розширювати , щоб матеріал, з \letстворенням копії вже існуючих речей. Після \let\blub=\def( =необов’язково) ви можете змінити початок eприкладу з кодового коду 13 пункту вище на \blub e{...та розважитися цим. Або краще, замість того , щоб ламати речі можна виправити (ви подивіться на це!) На Rприклад: \let\newr=R \catcode`R=13 \def R{I am an A\newr\newr\newr!}. Швидке запитання: чи могли ви перейменувати \newR?

  • Нарешті, так звані «помилкові простори». Це своєрідна тема табу, оскільки є люди, які стверджують, що репутація, зароблена на біржі стеків TeX - LaTeX , відповідаючи на "помилкові місця", не повинна розглядатися, а інші відверто не згодні. З ким ти згоден? Розмістіть свої ставки! Тим часом: TeX розуміє розрив лінії як пробіл. Спробуйте написати кілька слів з перервою рядка (не порожнім рядком ) між ними. Тепер додайте а %в кінці цих рядків. Це все одно, що ви "коментували" ці пробіли в кінці рядка. Це воно :)

(Сортування) скасування коду

Давайте зробимо цей прямокутник у чомусь (можливо) простішим:

{
\let~\catcode
~`A13
\defA#1{~`#113\gdef}
AGG#1{~`#113\global\let}
GFF\else
GHH\fi
AQQ{Q}
AII{\ifxQ}
AEE#1#2#3|{I#3#2#1FE{#1#2}#3|H}
ADD#1#2#3|{I#2FE{#1}#2#3|H}
ACC#1#2|{D{}#2Q|#1 }
ABBH#1 {HI#1FC#1|BH}
\gdef\S#1{\iftrueBH#1 Q }
}

Пояснення кожного кроку

кожен рядок містить одну єдину інструкцію. Ходімо по черзі, розбираючи їх:

{
Спочатку ми запускаємо групу, щоб зберегти деякі зміни (а саме зміни кодового коду) локальними, щоб вони не зіпсували вхідний текст.

\let~\catcode
В основному всі коди обфускування TeX починаються з цієї інструкції. За замовчуванням, як у звичайному TeX, так і в LaTeX, ~символ є одним активним символом, який може бути перетворений в макрос для подальшого використання. І найкращим інструментом для присвоєння коду TeX є зміни кодового коду, тому це, як правило, найкращий вибір. Тепер замість цього \catcode`A=13ми можемо написати ~`A13( =необов’язково):

~`A13
Тепер лист Aє активним символом, і ми можемо визначити його, щоб зробити щось:

\defA#1{~`#113\gdef}
Aтепер макрос, який бере один аргумент (який повинен бути іншим символом). Спочатку кодовий аргумент змінюється на 13, щоб він став активним: ~`#113(замініть на ~, \catcodeдодайте =і у вас є :) \catcode`#1=13. Нарешті, він залишає \gdef(глобальним \def) у вхідному потоці. Коротше кажучи, Aробить іншого персонажа активним і починає його визначення. Давайте спробуємо:

AGG#1{~`#113\global\let}
AGспочатку "активується" Gі робить \gdef, після чого наступне Gпочинає визначення. Визначення Gдуже схоже на визначення цього A, за винятком того, що замість \gdefнього робиться \global\let(немає \gletподібного \gdef). Словом, Gактивізує персонажа і робить його чимось іншим. Зробимо ярлики для двох команд, які ми використаємо пізніше:

GFF\else
GHH\fi
Тепер замість \elseі \fiми можемо просто використовувати Fі H. Набагато коротше :)

AQQ{Q}
Тепер ми використовуємо Aще раз , щоб визначити інший макрос, Q. Вищенаведене твердження в основному робить (менш заплутаною мовою) \def\Q{\Q}. Це не дуже цікаве визначення, але воно має цікаву особливість. Якщо ви не хочете зламати якийсь код, єдиний макрос, який розширюється, - Qце Qсам, тому він діє як унікальний маркер (його називають кварком ). Ви можете використовувати \ifxумовне для перевірки, чи аргумент макросу такий кварк із \ifx Q#1:

AII{\ifxQ}
тож ви можете бути впевнені, що знайшли такий маркер. Зауважте, що в цьому визначенні я видалив пробіл між \ifxі Q. Зазвичай це призведе до помилки (зауважте, що синтаксис підкреслює, що \ifxQце одне), але оскільки Qце кодовий код 13, він не може сформувати контрольну послідовність. Але будьте обережні, щоб не розширювати цей кварк, або ви застрягнете у нескінченному циклі, оскільки Qрозширюється, до Qякого розширюється, до Qякого ...

Тепер, коли попередні випуски зроблені, ми можемо перейти до відповідного алгоритму, щоб задати сеттерл. Завдяки токенізації TeX алгоритм повинен записуватися назад. Це тому, що під час виконання визначення TeX буде токенізувати (призначити кодові коди) символам у визначенні, використовуючи поточні настройки, наприклад, якщо я це роблю:

\def\one{E}
\catcode`E=13\def E{1}
\one E

Вихід є E1, тоді як якщо я зміню порядок визначень:

\catcode`E=13\def E{1}
\def\one{E}
\one E

вихід є 11. Це тому, що в першому прикладі визначення Eу токенізації було позначене буквою (кодовий код 11) до зміни кодового коду, тому це завжди буде буквою E. У другому прикладі, однак, Eспочатку було активовано, і лише потім \oneбуло визначено, і тепер визначення містить кодовий код 13, Eякий розширюється на 1.

Я, однак, не помічаю цього факту і переставляю визначення, щоб вони мали логічний (але не працює) порядок. У наступних параграфах ви можете припустити , що букви B, C, Dі Eє активними.

\gdef\S#1{\iftrueBH#1 Q }
(зауважте, що в попередній версії була невелика помилка, вона не містила остаточного пробілу у визначенні вище. Я помітив її лише під час написання цього запиту. Читайте далі, і ви побачите, чому нам потрібен той, щоб правильно припинити макрос. )
Спочатку ми визначаємо призначені для користувача макроси, \S. Цей не повинен бути активним символом, щоб мати дружній (?) Синтаксис, тому макрос для gwappins eht setterl є \S. Макрос починається з завжди справжнього умовного \iftrue(незабаром стане зрозуміло, чому), а потім викликає Bмакрос, за яким H(який ми визначили раніше \fi), щоб відповідати \iftrue. Потім залишаємо аргумент макросу, #1після якого пробіл і кварк Q. Припустимо, ми використовуємо \S{hello world}тоді вхідний потікмає виглядати приблизно так: \iftrue BHhello world Q␣(Я замінив останній пробіл таким, щоб візуалізація сайту не з'їла його, як це було в попередній версії коду). \iftrueце правда, тому вона розширюється, і ми залишаємося BHhello world Q␣. TeX це НЕ видалити \fi( H) після того , як умовно оцінюється, замість цього вона залишає його там , поки \fiНЕ буде на самому ділі розширюється. Тепер Bмакрос розгорнуто:

ABBH#1 {HI#1FC#1|BH}
Bце обмежений макрос, чий текст параметру є H#1␣, тому аргументом є все, що знаходиться між Hі пробілом. Продовжуючи приклад вище вхідного потоку перед розширенням BIS BHhello world Q␣. Bслідує H, як слід (інакше TeX призведе до помилки), тоді наступний пробіл знаходиться між helloі world, #1як і слово hello. І ось ми ділимо ввідний текст на пробіли. Yay: D Розширення Bвидаляє всі аж до першого місця з вхідного потоку і замінює на HI#1FC#1|BHс #1того hello: HIhelloFChello|BHworld Q␣. Зауважте, що є новий BHпізніше у вхідному потоці, щоб зробити хвостову рекурсіюBі обробляти пізніші слова. Після обробки цього слова обробляє Bнаступне слово, поки слово, яке підлягає обробці, не стане кварком Q. Останній пробіл після Qпотрібен, тому що для розмежованого макросу B потрібен один в кінці аргументу. З попередньою версією (див. Історію редагування) код не буде поводитись, якщо ви використовували \S{hello world}abc abc(проміжок між abcs зникне).

OK, назад у вхідний потік: HIhelloFChello|BHworld Q␣. Спочатку є H( \fi), що завершує початкове \iftrue. Тепер у нас це є (псевдокодування):

I
  hello
F
  Chello|B
H
world Q␣

Думка I...F...H- це насправді \ifx Q...\else...\fiструктура. У \ifxтест перевіряє , є чи (перший токен) слово схопив є Qкварк. Якщо немає нічого іншого, і виконання завершується, в іншому випадку що залишається: Chello|BHworld Q␣. Зараз Cрозширено:

ACC#1#2|{D#2Q|#1 }
Перший аргумент Cє НЕ виділяються, так що якщо не приготувався буде один маркер, другий аргумент обмежений |, так що після розширення C#1=hі #2=ello) вхідний потік: DelloQ|h BHworld Q␣. Зверніть увагу , що інший |ставляться там, і hз helloставляться після цього. Половина заміни робиться; перша буква - в кінці. У TeX легко схопити перший маркер списку токенів. Простий макрос \def\first#1#2|{#1}отримує першу літеру при використанні \first hello|. Останнє - це проблема, оскільки TeX завжди сприймає "найменший, можливо, порожній" список лексем як аргумент, тому нам потрібно кілька обхідних завдань. Наступний пункт у списку токенів D:

ADD#1#2|{I#1FE{}#1#2|H}
Цей Dмакрос є одним із найрізноманітніших і корисний у єдиному випадку, коли слово має одну букву. Припустимо, замість helloнас x. У цьому випадку потік введення буде DQ|x, а потім Dрозшириться (із #1=Qта #2порожнім) до:IQFE{}Q|Hx . Це аналогічно блоку I...F...H( \ifx Q...\else...\fi) в B, який побачить, що аргументом є кварк і перерве виконання, залишаючи лише xдля набору тексту. В інших випадках (повернення до helloприкладу), Dбуде розширюватися (з #1=eі #2=lloQ) за адресою: IeFE{}elloQ|Hh BHworld Q␣. Знову ж , I...F...Hбуде перевіряти , Qале зазнає невдачі і взяти \elseвладу: E{}elloQ|Hh BHworld Q␣. Тепер останній фрагмент цієї речіE макрос розшириться:

AEE#1#2#3|{I#3#2#1FE{#1#2}#3|H}
Текст параметра тут досить схожий на Cта D; перший і другий аргументи не визнаються, а останній розміщений на |. Вхідний потік виглядає наступним чином : E{}elloQ|Hh BHworld Q␣, потім Eрозширюється (з #1порожнім, #2=eі #3=lloQ): IlloQeFE{e}lloQ|HHh BHworld Q␣. Інший I...F...Hблок перевіряє кварк (який бачить lі повертається false): E{e}lloQ|HHh BHworld Q␣. Тепер Eзнову розгортається (з #1=eпорожнім,#2=l і #3=loQ): IloQleFE{el}loQ|HHHh BHworld Q␣. І знову I...F...H. Макрос робить ще кілька ітерацій, поки Qнарешті не знайдено і не trueбуде взято гілку: E{el}loQ|HHHh BHworld Q␣-> IoQlelFE{ell}oQ|HHHHh BHworld Q␣-> E{ell}oQ|HHHHh BHworld Q␣-> IQoellFE{ello}Q|HHHHHh BHworld Q␣. Тепер кварк знайдений і умовні Розкривається в: oellHHHHh BHworld Q␣. Phew.

Ой, чекай, що це? НОРМАЛЬНІ ЛИСТИ? О, малюк! Листи , нарешті , знайшли і TeX запише oell, то зв'язка H( \fi) будуть знайдені і розширені (нічого) , що виходить з вхідного потоку з: oellh BHworld Q␣. Тепер у першому слові поміняються перша і остання букви, і теХ, що знаходить наступне, - друге, Bщоб повторити весь процес для наступного слова.

}
Нарешті ми закінчуємо групу, розпочату туди, щоб усі місцеві завдання були скасовані. Місцеві призначення є catcode зміни букв A, B, C, ... , які були зроблені макроси так , що вони повертаються до свого нормального значення букви і може безпечно використовуватися в тексті. І це все. Тепер \Sвизначений там макрос запустить обробку тексту, як зазначено вище.

Цікавою справою цього коду є те, що він повністю розширюється. Тобто, ви можете сміливо використовувати його в рухомих аргументах, не переживаючи, що він вибухне. Ви навіть можете скористатися кодом, щоб перевірити, чи остання буква слова однакова другої (з будь-якої причини, що вам знадобиться) у \ifтесті:

\if\S{here} true\else false\fi % prints true (plus junk, which you would need to handle)
\if\S{test} true\else false\fi % prints false

Вибачте за (мабуть, занадто) багатослівне пояснення. Я намагався зробити це максимально зрозумілим і для не TeXies :)

Підсумок для нетерплячих

Макрос \Sпопередньо вводить активний символ, Bякий захоплює списки жетонів, обмежених остаточним пробілом, і передає їх C. Cбере перший маркер у цьому списку і переміщує його до кінця списку токенів і розширює Dтим, що залишилося. Dперевіряє, чи "те, що залишається" порожнє, і в цьому випадку знайдено однолітерне слово, тоді не робіть нічого; інакше розширюється E. Eпробирається через список токенів, поки він не знайде останню букву в слові, і коли він знайдеться, він залишає останню букву з наступною серединою слова, після чого слідує перша буква, залишена в кінці потоку лексеми від C.


2
Я б хотів повного пояснення цього. Мені дуже цікаво, як це працює!
LambdaBeta

1
@LambdaBeta Я можу це зробити, але не зараз. Тримайся, і я
підкажу

1
@LambdaBeta Готово! Вибачте, я занадто багато слова іноді :-)
Феліпе Олейник

13

JavaScript (ES6),  39  36 байт

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

В якості роздільника використовується подача ліній.

s=>s.replace(/(.)(.*)(.)/g,'$3$2$1')

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


5
(.)(.*)(.)це смайлик Total Recall?
MikeTheLiar

1
@MikeTheLiar Вигляд, я думаю. : D
Арнольд

Призначення вказує, що рядок містить роздільник.
Cees Timmerman

@CeesTimmerman Я не впевнений, що ти маєш на увазі. Цей код очікує, що передача рядків буде відокремлена, і тому приймає рядки з стрічковими каналами як вхідні дані. (Нижній колонтитул посилання TIO перетворює пробіли на канали ліній, а потім назад в пробіли для читання.)
Арнольд,

"Дано рядок алфавітних символів ASCII , а також один інший символ, який слід використовувати як роздільник (для розділення кожного слова) " - Nm, я вважав, що це окремий параметр.
Cees Timmerman

11

Сітківка ,8 5 байт

,V,,`

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

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

Як роздільник використовується новий рядок. Ми використовуємо зворотний етап Retina та деякі межі. Перша межа - це відповідність, до якої слід застосувати реверс, тому ми обираємо їх усі ,. Тоді ми хочемо поміняти першу та останню букву кожної відповідності, тому ми беремо кожну букву в діапазоні, ,,що перекладається на діапазон від початку до кінця з розміром кроку нулем.


Dangit, я просто шукав через документи щось подібне, щоб оновити свою відповідь, але ти перебив мене на це. Я знав про це V, але не знав, що його можна використовувати з такими індексами 1,-2. Хороший!
Кевін Круїссен

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

2
Ви дійсно маєте рацію, що вона може бути коротшою без граничного діапазону, оскільки, здається, це працює 5-байтний (наводиться як приклад у нижній частині Лімітів кроків у документах).
Кевін Круїссен

@KevinCruijssen Приємно! Не можу повірити, що я пропустив це.
FryAmTheEggman

3
Отже, 5 байт і лише 3 різні символи? Це мінімалістично.
Cœur

9

Пепе , 107 105 байт

REEeREeeEeeeeerEEreREEEeREEEEEEeREEEErEEREEEEEEEreererEEEeererEEEerEEeERrEEEeerEEeerereeerEEEEeEEEReEeree

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

Пояснення:

Повідомлення про коментарі: command-explanation -> (stack) // explanation

REEe # input -> (R)
REeeEeeeee # push space to last -> (R) // this prevents an infinite loop

rEE # create loop labeled 0 and automatically push 0 
  re # pop 0 -> (r)
  REEEe # go to last item -> (R)
  REEEEEEe # ...then copy the char to other stack
  REEEE # go to first item -> (R)

  rEE # create loop labeled 32 // detect space
    REEEEEEE # move item to other stack (R)
  ree # do this while char != 32

  re # pop 32 -> (r)
  rEEEee # push item (dup to end) -> (r)
  re # ...then pop -> (r)
  rEEEe rEEeE # go to 2nd to last item -> (r)
  RrEEEee # push the item (R flag: dup to first) -> (r)
  rEEee # go to next -> (r) //
  re # ...then pop -> (r)
  reee rEEEEeEEE # out all as char then clear -> (r)
  ReEe # out 32 as char -> (R)
ree # do this while stack != 0

Як це працює?
ліртосіаст

@lirtosiast пояснення додано
u_ndefined


6

laskelH , 71 байт

h=reverse
s(x:y:o)=a:h(x:r)where(a:r)=h$y:o
s o=o
f=unwords.map s.words

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

Приклад в / вихід:

Swap the first and last letter in each word
This also works with single letter words like a

It is basically just a straight up implementation in which
I for words consisting of two or more letters cons the head
of the reversed tail on the reverse of the original head consed
on the reversed tail

Note that the rules say that we only have to support one kind
of separator - I am choosing spaces Technically it works with
other whitespace as well, but it will turn everything into spaces
in the end Line endings in this example usage are handled separately
to make the example output look nicer
pwaS eht tirsf dna tasl rettel ni hace dorw
shiT olsa sorkw hitw eingls rettel sordw eikl a

tI si yasicallb tusj a ttraighs pu nmplementatioi ni hhicw
I rof sordw gonsistinc fo owt ro eorm setterl sonc eht deah
fo eht deverser lait no eht eeversr fo eht lriginao deah donsec
no eht deverser lait

eotN that eht suler yas that ew ynlo eavh ot tuppors eno dink
fo reparatos - I ma ghoosinc spaces yechnicallT ti sorkw hitw
rtheo ehitespacw sa ,ellw tub ti lilw nurt gverythine onti spaces
ni eht dne einL sndinge ni shit example esagu era dandleh yeparatels
ot eakm eht example tutpuo kool ricen
```

1
Призначення в whereпункті може бути перенесено на прив'язку в охороні, щоб зберегти 5 байт: Спробуйте це в Інтернеті!
Лайконі

1
Я бачу, що ви там зробили з назвою "Haskell" у назві. Я зробив те ж саме, на мою відповідь PHP.
640 Кб

5

05AB1E , 10 байт

#vyRćsRćðJ

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


-3 Завдяки @Kevin Cruijssen .

#           | Split into words.
 vy         | For each word...
   RćsRć    | Reverse, split head, swap, reverse, split tail
        ðJ  | Join by spaces.


1
@KevinCruijssen Я чесно хочу видалити його і надати вам, це було на 99% вашої мозкової сили на впорядкування аргументів ха-ха.
Чарівна восьминога урна

1
Знайшли 9-байт, але він працює лише у застарілій версії:|ʒRćsRćJ,
Кевін Круїйсен

1
Шкода, що у нас немає loop_as_long_as_there_are_inputs, тоді я б знав 8-байтний: [RćsRćJ,Цей 8-байтний метод [ніколи не виводить теоретично, однак лише тоді, коли у вас немає пам’яті або часу, як у TIO (і для цього потрібна трейлінг новий рядок у введенні, інакше він продовжить використовувати останнє слово) ..
Кевін Круїссен

1
На жаль, вам потрібно, ð¡оскільки введення одного слова можливо, але ð¡εćsÁì}ðýтакож працює в 10 байт.
Емінья

5

J , 23 17 байт

({:,1|.}:)&.>&.;:

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


Дуже приємна хитрість поміняти місцями перші / останні букви обертанням та застосуванням 1 A.!
Галена Іванова

1
1&A.&.(1&|.)->, ({:,1|.}:)і тоді ви можете видалити::]
ngn

Дивовижно, дякую
FrownyFrog

Дійсно дивовижно! Я вкотре дивуюсь, наскільки простим і елегантним може бути рішення, але лише після того, як я побачу, що його робить хтось інший.
Гален Іванов

4

Рубі с -p, 42 41 29 байт

gsub /(\w)(\w*)(\w)/,'\3\2\1'

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



@Shaggy дякую за голову вгору. Якщо ви подивитесь на історію моєї публікації, це свідчить про те, що я пробув 8 місяців без жодних відповідей, тому я, ймовірно, пропустив кілька записок за цей час, ха-ха
Value Ink

Досить впевнений, що консенсус було змінено більше 8 місяців тому, але про всяк випадок, коли ви його пропустили: "неконкурентоспроможний" - це вже не річ.
Кудлатий

Чудово зроблено. Я думаю, що за правилами ви можете використовувати нові рядки як роздільник і замінити \ws на .s.
гістократ





3

Пробіл , 179 байт

[N
S S S N
_Create_Label_OUTER_LOOP][S S S N
_Push_n=0][N
S S T   N
_Create_Label_INNER_LOOP][S N
S _Duplicate_n][S N
S _Duplicate_n][S N
S _Duplicate_n][T   N
T   S _Read_STDIN_as_character][T   T   T   _Retrieve_input][S S S T    S T T   N
_Push_11][T S S T   _Subtract_t=input-11][N
T   T   S S N
_If_t<0_jump_to_Label_PRINT][S S S T    N
_Push_1][T  S S S _Add_n=n+1][N
S N
T   N
_Jump_to_Label_INNER_LOOP][N
S S S S N
_Create_Label_PRINT][S S S T    N
_Push_1][T  S S T   _Subtract_n=n-1][S N
S _Duplicate_n][S N
S _Duplicate_n][N
T   S N
_If_n==0_jump_to_Label_PRINT_TRAILING][T    T   T   _Retrieve][T    N
S S _Print_as_character][S S S N
_Push_s=0][N
S S S T N
_Create_Label_PRINT_LOOP][S S S T   N
_Push_1][T  S S S _Add_s=s+1][S N
S _Duplicate_s][S T S S T   S N
_Copy_0-based_2nd_n][T  S S T   _Subtract_i=s-n][N
T   S N
_If_0_Jump_to_Label_PRINT_TRAILING][S N
S _Duplicate_s][T   T   T   _Retrieve][T    N
S S _Print_as_character][N
S T S T N
_Jump_to_Label_PRINT_LOOP][N
S S N
_Create_Label_PRINT_TRAILING][S S S N
_Push_0][T  T   T   _Retrieve][T    N
S S _Print_as_character][S S S T    S S T   N
_Push_9_tab][T  N
S S _Print_as_character][N
S N
S N
_Jump_to_Label_OUTER_LOOP]

Букви S(пробіл), T(вкладка) та N(новий рядок) додаються лише як підкреслення.
[..._some_action]додано лише як пояснення.

Вкладка як роздільник. Вхід повинен містити зворотний новий рядок (або вкладку), інакше програма не знає, коли зупинитись, оскільки введення даних у Whitespace може бути виконано лише одним символом.

Спробуйте це в Інтернеті (лише із необробленими пробілами, вкладками та новими рядками).

Пояснення в псевдокоді:

У Whitespace є лише стек і купа, де купа - це карта з ключем і значенням (обидва цілі числа). Вхідні дані можуть читати лише одне ціле число чи символ за один раз, які завжди розміщуються в купі як цілі числа, а потім можуть бути отримані та висунуті до стеку із визначеними кучами-адресами (картами-клавішами). У моєму підході я зберігаю все слово за куповими адресами (клавішами карт)[0,...,word_length], а потім витягніть символи для друку один за одним у тому порядку, який ми хотіли б, коли вкладка (або новий рядок) зустрічається як роздільник.

Start OUTER_LOOP:
  Integer n = 0
  Start INNER_LOOP:
    Character c = STDIN as character, saved at heap-address n
    If(c == '\t' OR c == '\n'):
      Jump to PRINT
    n = n + 1
    Go to next iteration of INNER_LOOP

  PRINT:
    n = n - 1
    If(n == 0): (this means it was a single-letter word)
      Jump to PRINT_TRAILING
    Character c = get character from heap-address n
    Print c as character
    Integer s = 0

    Start PRINT_LOOP:
      s = s + 1
      If(s - n == 0):
        Jump to PRINT_TRAILING
      Character c = get character from heap-address s
      Print c as character
      Go to next iteration of PRINT_LOOP

    PRINT_TRAILING:
      Character c = get character from heap-address 0
      Print c as character
      Print '\t'
      Go to next iteration of OUTER_LOOP

Програма закінчується помилкою, коли вона намагається прочитати символ, коли жоден не вказаний у TIO (або він зависає, чекаючи введення в деяких компіляторах Whitespace, таких як vii5ard ).


3

Мова Вольфрама (Mathematica) , 58 байт

StringReplace[#,a:u~~w:u..~~b:u:>b<>w<>a/.{u->Except@#2}]&

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

-22 байти від @attinat

-12 байт від @ M.Stern


70 байт , використовуючи StringReplaceпри StringExpressionх
attinat

1
64 байти, використовуючи StringTakeзамість StringReplace:StringRiffle[StringSplit@##~StringTake~{{-1},{2,-2},{1}},#2,""]&
Роман

2
Ось більш прямий підхід:StringReplace[#, a : u ~~ w : u .. ~~ b : u :> b <> w <> a /. {u -> Except@#2}] &
М. Штерн

1
{та} необов’язкові :)
М. Штерн

1
55 байт , також фіксує 2-символьні слова
attinat



2

Japt -S , 10 байт

Переконаний, що має бути коротший підхід (і я мав рацію ), але це робити зараз.

¸ËhJDg)hDÌ

Спробуй це

¸ËhJDg)hDÌ     :Implicit input of string
¸              :Split on spaces
 Ë             :Map each D
  h            :  Set the character at
   J           :    Index -1 to
    Dg         :    The first character in D
      )        :  End set
       h       :  Set the first character to
        DÌ     :    The last character in D
               :Implicit output, joined by spaces

Набагато коротший, ніж мій 12 байт:¸®Ì+Zs1J +Zg
Втілення невігластва

@EmbodimentofIgnorance, саме з цього я і почав, але це не вдалося б на словах з одним символом. Ти можеш зберегти байт на цьому, хоча, за допомогою ¸®ÎiZÌ+Zs1J.
Кудлатий

1
@EmbodimentofIgnorance Знайшов 7 байт
Олівер

2

sed, 64 байт

sed -E 's/\b([[:alpha:]])([[:alpha:]]*)([[:alpha:]])\b/\3\2\1/g'

Звичайно, ми могли б використовувати .замість цього [[:alpha:]], але насправді це повинно бути [^ ], що зменшує його до 43, але розриви на пунктуацію та інше. Використання [a-zA-Z]підводить його до 55, до цього моменту я просто блукаю за тими милими, милими людськими читаними істотами ...
Багатий

2
You do not need to handle punctuation; all of the inputs will only consist of the letters a through z, separated by a delimiter, all of a uniform case.Іншими словами, вам не потрібно турбуватися про те, що пунктуація "зламає" ваш код, і ви можете просто сміливо йти [^ ];)
Value Ink

@ValueInk Так, але тоді це [^ ]повинно бути таким, [^[:space:]]що приводить його до 67 знаків.
Багатий

"роздільник" означає, що ви можете переконатися, що роздільник завжди є звичайним пробілом. Хто все-таки використовує вкладки у реченні ??
Значення чорнила

Гаразд. Здається, що «кодовий гольф» - це гра, в якій ви повинні знайти способи отримати безпілотника, щоб кинути м'яч у лунку, а не робити насправді роботу. Дякую за лайно-ласкаво просимо.
Багатий

2

sed , 34 байт

І, мабуть, ідея шаблону буде працювати з більшістю інструментів RE (і я знаю, що існують відмінності між стандартними RE та розширеними RE).

s,\b\(\w\)\(\w*\)\(\w\)\b,\3\2\1,g

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


1
Ласкаво просимо до PPCG! Думає, що жадібний характер регулярних вирівнювань означає, що ви можете вирізати \bз матчу: Спробуйте це в Інтернеті!
Значення чорнила

Погодився @ValueInk - але я був точний з матчем. Видалення \bволі призведе до 30 байт.
PJF

Використовуйте -E для розширеного регулярного вираження, і ви можете використовувати недиспективні круглі дужки. Використовуйте .для замінених символів, і ви можете втратити ще два символи. Це зводить ваше до 26 байт; одне з найменших читабельних рішень. s,\b(.)(\w*)(.)\b,\3\2\1,g
Багатий

1
- Ні, я помиляюся, вам потрібні \ws на кінцях. s,\b(\w)(\w*)(\w)\b,\3\2\1,g28 символів.
Багатий

Приємна робота @rich, але, як я вже говорив, я знаю про стандартну та розширену RE. Я просто вирішив зробити його стандартним і читабельним. Будуть потрібні якіри, які я знехтував зазначити у своїй відповіді на ValueInk.
PJF

2

Рубін, 53 байти

gets.split(" ").map{|z|print z[-1]+z[1..-2]+z[0]," "}

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

Безголовки:

gets.split(" ").map {|z|
    print z[-1] + z[1..-2] + z[0], " "
}

Ласкаво просимо до PPCG! Друк кожного слова на новому рядку повинен бути добре, але ваше старе рішення не pбуло корисним, оскільки це додало лапки до результату. Ви завжди можете використовувати putsзамість цього, оскільки один автоматично додає новий рядок і коротший за print! Крім того, якщо ви телефонуєте splitбез аргументів, він автоматично розбивається на пробіли.
Значення чорнила

2

8088 Асамблея, IBM PC DOS, 39 38 байт

$ xxd pwas.com
00000000: d1ee ac8a c8fd 03f1 c604 244e 8bfe ac3c  ..........$N...<
00000010: 2075 098a 2586 6402 8825 8bfe e2f0 b409   u..%.d..%......
00000020: ba82 00cd 21c3

Не зібрано:

D1 EE       SHR  SI, 1          ; point SI to DOS PSP (080H) 
AC          LODSB               ; load string length into AL 
8A C8       MOV  CL, AL         ; load string length into CX for loop
FD          STD                 ; set LODSB to decrement 
03 F1       ADD  SI, CX         ; point SI to end of string 
C6 04 24    MOV  BYTE PTR[SI], '$' ; put a '$' DOS string terminator at end 
4E          DEC  SI             ; start at last char of word 
8B FE       MOV  DI, SI         ; point DI to last char of word 
        CHR_LOOP: 
AC          LODSB               ; load next (previous?) char into AL 
3C 20       CMP  AL, ' '        ; is it a space? 
75 0A       JNE  END_CHR        ; if so, continue loop 
8A 25       MOV  AH, [DI]       ; put last char in AH 
86 64 02    XCHG AH, [SI][2]    ; swap memory contents of first char with last 
                                ; (unfortunately XCHG cannot swap mem to mem)
88 25       MOV  [DI], AH       ; put first char value into last char position 
8B FE       MOV  DI, SI         ; point DI last char of word 
        END_CHR:
E2 EF       LOOP CHR_LOOP       ; continue loop 
B4 09       MOV  AH, 9          ; DOS display string function 
BA 0082     MOV  DX, 082H       ; output string is at memory address 82H 
CD 21       INT  21H            ; display string to screen 
C3          RET                 ; return to DOS 

Автономний виконуваний ПК DOS. Введення через аргументи командного рядка, вихід на екран.

enter image description here

Завантажте та протестуйте PWAS.COM .



1

Пакетна, 141 байт

@set t=
@for %%w in (%*)do @call:c %%w
@echo%t%
@exit/b
:c
@set s=%1
@if not %s%==%s:~,1% set s=%s:~-1%%s:~1,-1%%s:~,1%
@set t=%t% %s%

Приймає введення як параметри командного рядка. Маніпуляція з рядками в кращому випадку є грішною в Batch, і необхідність вводити однозначні слова в окремі регістри не допомагає.


1

C # (Visual C # Interactive Compiler) , 90 байт

n=>n.Split().Any(x=>WriteLine(x.Length<2?x:x.Last()+x.Substring(1,x.Length-2)+x[0])is int)

Використовує новий рядок як роздільник, хоча можна використовувати будь-який пробіл.

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


SelectMany (тобто зіставлення та вирівнювання) на 84 байти, але виводить єдиний пробіл. Спробуйте в Інтернеті!
мій займенник monicareinstate


1

Ява, 110 109 байт

-1 байт, використовуючи нову лінію для деліметра

s->{int l;for(var i:s.split("\n"))System.out.println(i.charAt(l=i.length()-1)+i.substring(1,l)+i.charAt(0));}

ТІО


Чи працює це для одно буквених слів?
Ніл

@Neil ні, тому що я поганий. Я виправлю пізніше.
Бенджамін Уркхарт

109 , використовуючи новий рядок як роздільник
Втілення Невідомості

1

Хаскелл , 75 74 байт

Виправлена ​​помилка, на яку вказав Кубік, а також на 1 байт.

f=unwords.map(#v).words
x#g=g(r$tail x)++[x!!0]
r=reverse
v[]=[]
v x=r$x#r

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


map gкоротше, ніж(g<$>)
кубічний

1
Крім того, якщо ви подивитесь на свій тестовий випадок, ви побачите, що він не працює на одну букву, це перетворюється aнаaa
Cubic

1

Scala, 100 байт

(b:String,c:String)=>b.split(c)map(f=>f.tail.lastOption++:(f.drop(1).dropRight(1)+f.head))mkString c

1

T-SQL, 126 байт

SELECT STRING_AGG(STUFF(STUFF(value,1,1,RIGHT(value,1)),LEN(value),1,LEFT(value,1)),' ')
FROM STRING_SPLIT((SELECT*FROM t),' ')

Введення здійснюється через попередньо існуючу таблицю t з полем varchar v , відповідно до наших стандартів IO .

Читаючи ззаду наперед, STRING_SPLIT розбиває рядок на окремі рядки через роздільник, STUFFмодифікує символи у визначених положеннях, а потім знову STRING_AGGпереміщує їх разом.

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