물웅덩이와 물웅덩이


30

또는 "각 단어의 첫 글자와 마지막 글자를 바꾸십시오"

당신의 도전은, 알파벳 ASCII 문자의 문자열과 분리 문자 (각 단어를 분리하기 위해)로 사용할 다른 문자가 주어지면 각 단어의 첫 글자와 마지막 글자를 바꾸는 것입니다. 한 글자로 된 단어는 그대로 두십시오.

예제 / 테스트 사례는 소문자와 공백을 구분 기호로 사용합니다.

구두점을 처리 할 필요는 없습니다. 모든 입력은 문자 a ~ z로 구분되며 구분 기호로 구분되며 모든 균일 한 경우입니다.

예를 들어 문자열 "hello world"를 사용하면

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!(장소에 구두점을 유지)?
Phelype Oleinik

3
@PhelypeOleinik 구두점을 처리 할 필요는 없습니다. 모든 입력은 문자 a부터 z까지, 그리고 모든 균일 한 문자로 구성됩니다.
스파클 포니 동지

4
두 번째 단락은 구분 기호로 사용할 다른 문자뿐만 아니라 다른 문자도 읽는 반면, 네 번째 단락 은 공백으로 구분됩니다 . 어떤거야?
Adám

@ Adám 알파벳이 아닌 문자. 명확히하기 위해 편집 할 것입니다.
스파클 포니 동지

1
@BenjaminUrquhart 예. 원하는 경우 입력을 함수 인수로 사용할 수 있습니다.
스파클 포니 동지

답변:


59

TeX, 216 바이트 (4 줄, 각 54 자)

바이트 수에 관한 것이 아니기 때문에 typeset 출력의 품질에 관한 것입니다 :-)

{\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

산출:

여기에 이미지 설명을 입력하십시오


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는 매크로 확장 언어입니다. 예를 들어 TeX를 인쇄하도록 정의한 \def\sayhello#1{Hello, #1!}다음 쓸 \sayhello{Code Golfists}수 있습니다 Hello, Code Golfists!. 이것을 "무제한 매크로"라고하며이를 중괄호로 묶는 첫 번째 (이 경우에만) 매개 변수를 제공합니다. TeX는 매크로가 인수를 잡을 때 이러한 중괄호를 제거합니다. 당신은 9 개의 매개 변수를 사용할 수 있습니다 \def\say#1#2{#1, #2!}\say{Good news}{everyone}.

  • undelimited 매크로의 대응은, 당연히, 사람을 구분됩니다 : 당신은 이전의 정의는 조금 더 만들 수있는 의미 론적 : \def\say #1 to #2.{#1, #2!}. 이 경우 매개 변수 뒤에 소위 매개 변수 text가 있습니다. 이러한 매개 변수 텍스트는 매크로의 인수를 구분합니다 ( #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]는, catcode 11있는 \hello동안, 하나의 제어 시퀀스 인 \he11o제어 순서입니다 \he두 문자 다음에 1문자 다음에이 o있기 때문에, 1경우 catcode 11 아닙니다 I 한 \catcode`1=11에 그 시점에서, \he11o하나 개의 제어 순서 일 것이다. 중요한 것은 TeX가 처음 등장하는 캐릭터를 볼 때 고양이 코드가 설정되고 그러한 고양이 코드가 정지 된다는 것입니다 . (약관이 적용될 수 있습니다)

    • catcode 12 는 대부분 다른 문자 0"!@*(?,.-+/등입니다. 그들은 종이에 물건을 쓸 때만 사용되므로 가장 특수한 유형의 catcode입니다. 그런데 TeX를 쓰는 사람은 누구입니까?!? (이용 약관이 적용될 수 있음)

    • catcode 13 , 지옥 :) 정말. 독서를 멈추고 인생에서 무언가를하십시오. catcode 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코드를 작성합니다! 이것이 catcode 13입니다. 나는 차분하다! 계속 갑시다.

  • 자 이제 그룹화합니다. 이것은 매우 간단합니다. 그룹에서 수행 된 모든 할당 ( \def할당 작업, \let다른 작업)은 그룹에 수행 된 할당이 전역이 아닌 한 해당 그룹이 시작되기 이전의 상태로 복원됩니다. 그룹을 시작하는 방법에는 여러 가지가 있으며 그 중 하나는 catcode 1 및 2 문자입니다 (다시 catcodes). 기본적 {으로 catcode 1 또는 begin-group이고 }catcode 2 또는 end-group입니다. 예 : \def\a{1} \a{\def\a{2} \a} \a이 인쇄 1 2 1. 그룹 외부 \a1이고 내부는로 다시 정의되었으며 2그룹이 종료되면로 복원되었습니다 1.

  • \let작업은과 같은 다른 할당 작업 \def이지만 다소 다릅니다. 으로 \def당신은 정의 와 함께, 물건 확장됩니다 매크로 \let가 이미 존재하는 것들의 복사본을 만듭니다. 이후 \let\blub=\def( =선택 사항) e위의 catcode 13 항목에서 예제 시작을 변경하여 \blub e{...재미있게 사용할 수 있습니다. 또는 더 나은 방법으로 물건을 깨는 대신 예제를 고칠 수 있습니다 (보시겠습니까!) . 빠른 질문 : 이름을 바꿀 수 있습니까?R\let\newr=R \catcode`R=13 \def R{I am an A\newr\newr\newr!}\newR

  • 마지막으로 소위“스퓨리어스 스페이스”. 이것은 “스퓨리어스 스페이스”질문에 대한 답변으로 TeX-LaTeX Stack Exchange 에서 얻은 명성 이 고려되지 않아야한다고 주장하는 사람들이 있고 다른 사람들은 전적으로 동의하지 않기 때문에 금기 사항 입니다. 누구에 동의하십니까? 베팅하세요! 한편 : 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 }
}

각 단계에 대한 설명

각 줄에는 하나의 단일 명령이 포함됩니다. 하나씩 해보자.

{
먼저 입력 텍스트를 엉망으로 만들지 않도록 일부 변경 사항 (즉, catcode 변경 사항)을 로컬로 유지하기 위해 그룹을 시작합니다.

\let~\catcode
기본적으로 모든 TeX 난독 화 코드는이 명령어로 시작합니다. 기본적으로 일반 TeX 및 LaTeX에서 ~캐릭터는 나중에 사용할 수 있도록 매크로로 만들 수있는 하나의 활성 캐릭터입니다. TeX 코드를 이상하게 만드는 가장 좋은 도구는 catcode 변경 사항이므로 일반적으로 이것이 최선의 선택입니다. 이제 \catcode`A=13우리는 다음과 같이 쓸 수 있습니다 ~`A13( =선택 사항).

~`A13
이제 글자 A는 활동적인 캐릭터이며, 우리는 그것을하기 위해 그것을 정의 할 수 있습니다 :

\defA#1{~`#113\gdef}
A이제 하나의 인수 (다른 문자 여야 함)를 취하는 매크로입니다. 첫 번째 인수의 catcode은 활성화합니다 (13)로 변경됩니다 : ~`#113합니다 (교체 ~\catcode하고, 추가 =하고, 당신은 : \catcode`#1=13). 마지막으로 입력 스트림에 \gdef(global \def)을 남깁니다 . 즉, A다른 캐릭터를 활성화하고 정의를 시작합니다. 해 봅시다:

AGG#1{~`#113\global\let}
AG먼저 "활성화" G하고 수행 \gdef하고 다음 G에 정의가 시작됩니다. 의 정의는 G매우 유사하다 A의, 대신에를 제외시켰다 \gdef그것은이하는 \global\let(A가없는 \glet\gdef). 한마디 G로 캐릭터를 활성화하고 다른 캐릭터로 만듭니다. 나중에 사용할 두 가지 명령에 대한 바로 가기를 만들어 보겠습니다.

GFF\else
GHH\fi
이제 대신은 \else\fi우리는 간단하게 사용할 수 있습니다 FH. 훨씬 더 짧은 :)

AQQ{Q}
이제 A다시 매크로를 사용 하여 다른 매크로를 정의 Q합니다. 위의 진술은 기본적으로 (덜 난독 한 언어로) 수행 \def\Q{\Q}합니다. 이것은 굉장히 흥미로운 정의는 아니지만 흥미로운 특징을 가지고 있습니다. 일부 코드를 깨지 않으려는 경우 확장되는 유일한 매크로 QQ자체이므로 고유 마커처럼 작동합니다 ( Quark ). \ifx조건부를 사용하여 매크로의 인수가 다음과 같은 쿼크인지 테스트 할 수 있습니다 \ifx Q#1.

AII{\ifxQ}
그런 마커를 찾은 것을 확신 할 수 있습니다. 이 정의에서 \ifx와 사이의 공백을 제거했습니다 Q. 일반적으로 이것은 오류로 이어질 것입니다 (구문 하이라이트 \ifxQ는 한 가지 라고 생각합니다 ). 현재 Qcatcode 13이므로 제어 시퀀스를 형성 할 수 없습니다. 그러나,이 쿼크를 확장하거나 때문에 무한 루프에 갇혀거야하지 않도록주의 Q가 팽창가 Q되는 확장 Q된 ...

예비 작업이 완료되었으므로 적절한 알고리즘으로 이동하여 설정을 수행 할 수 있습니다. TeX의 토큰 화로 인해 알고리즘을 거꾸로 작성해야합니다. 정의를 할 때 TeX는 현재 설정을 사용하여 정의의 문자에 토큰 화 (catcodes 할당)하므로 예를 들어 다음과 같은 경우입니다.

\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에서 정의 의 in은 catcode가 변경되기 전에 문자 (catcode 11)로 토큰 화 되었기 때문에 항상 letter가 E됩니다. 그러나 두 번째 예에서는 E먼저 활성화 \one된 후에 만 정의되었으며 이제 정의에는 E로 확장 되는 catcode 13 이 포함되어 있습니다 1.

그러나 나는이 사실을 간과하고 논리적 인 (그러나 작동하지 않는) 순서를 갖도록 정의를 재정렬합니다. 다음 단락에서는 글자가 있다고 가정 할 수 있습니다 B, C, D, 및 E활성화됩니다.

\gdef\S#1{\iftrueBH#1 Q }
(이전 버전에는 작은 버그가 있었으며, 위의 정의에 마지막 공간이 포함되어 있지 않습니다.이 글을 쓰는 동안 만 눈치 Read습니다. 계속 읽으면 매크로를 제대로 종료하기 위해 왜 필요한지 알 수 있습니다. )
먼저 사용자 수준 매크로를 정의합니다 \S. 이 문자는 친숙한 (?) 구문을 갖기 위해 활성 문자가 아니어야하므로 setterl의 gwappins에 대한 매크로는 \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공백 사이 에 있습니다. 확장하기 전에 입력 스트림 위의 예를 계속하면 B입니다 BHhello world Q␣. B따른다 H는 (달리 텍스 에러를 제기 할)로한다, 그 다음 공간 사이 hello하고 world있으므로, #1단어이다 hello. 그리고 여기에 입력 텍스트를 공백으로 분할해야합니다. 야호 :의 D를 확장 B하여 입력 스트림을 대체에서 첫 번째 공간으로 제거합니다 모든 것을 최대 HI#1FC#1|BH#1되는 hello: HIhelloFChello|BHworld Q␣. BH입력 스트림에 꼬리 재귀를 수행하기 위해 나중에 새로운 것이 있음에 유의하십시오.B나중에 단어를 처리합니다. 이 단어가 처리 된 후 처리 B될 단어가 쿼크가 될 때까지 다음 단어가 처리 됩니다 Q. Q구분 된 매크로 는 인수의 끝에 하나 가 필요하므로 마지막 공백 이 필요 B 합니다 . 이전 버전 (편집 기록 참조)을 사용하면 코드가 제대로 작동하지 않습니다 \S{hello world}abc abc( abcs 사이의 공백 이 사라짐).

다시 입력 스트림으로 돌아갑니다 HIhelloFChello|BHworld Q␣. 먼저 초기를 완료하는 H( \fi)가 \iftrue있습니다. 이제 우리는 (의사 코드)이 있습니다 :

I
  hello
F
  Chello|B
H
world Q␣

I...F...H생각은 사실입니다 \ifx Q...\else...\fi구조. \ifx워드 (제 1의 토큰) 경우가 잡고 테스트 검사가있다 Q쿼크. 수행 할 다른 작업이없고 실행이 종료되면 남은 것은 다음과 같습니다 Chello|BHworld Q␣.. 이제 C확장되었습니다 :

ACC#1#2|{D#2Q|#1 }
의 첫 C번째 인수는 구분되지 않으므로 단일 토큰이 |되므로 두 번째 인수는로 구분 되므로 입력 스트림 의 C(with #1=hand #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}
여기의 매개 변수 텍스트는 Cand와 매우 유사합니다 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␣. 휴

잠깐, 이것들은 무엇입니까? 정상적인 편지? 오 소년! 문자가 마침내 발견되고 TeX가 oell기록한 다음 H( \fi) 무리 가 발견되고 확장되어 (아무것도) 입력 스트림을 다음과 같이 남겨 둡니다 oellh BHworld Q␣. 이제 첫 번째 단어는 첫 번째와 마지막 문자가 바뀌었고 TeX가 다음에 찾는 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
트윗 담아 가기 죄송합니다, 때때로 너무 장황합니다 :-)
Phelype Oleinik

13

자바 스크립트 (ES6),  39  36 바이트

@FryAmTheEggman 덕분에 3 바이트 절약

줄 바꿈을 구분자로 사용합니다.

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

온라인으로 사용해보십시오!


5
(.)(.*)(.)총 리콜 이모티콘인가요?
MikeTheLiar

1
@MikeTheLiar 종류의 것 같아요. : D
Arnauld

할당은 문자열에 구분 기호가 포함되도록 지정합니다.
Cees Timmerman

@CeesTimmerman 무슨 말인지 잘 모르겠습니다. 이 코드는 줄 바꿈을 구분 기호로 예상하므로 줄 바꿈이 입력 된 문자열을 입력으로 사용합니다. TIO 링크의 바닥 글은 공백을 줄 바꿈으로 변환 한 다음 다시 읽기 쉽게하기 위해 공백으로 변환합니다.
Arnauld

"알파벳으로 된 ASCII 문자 와 다른 문자를 구분자로 사용하여 (각 단어를 구분하기 위해) "-Nm, 나는 그것이 별도의 매개 변수라고 생각했습니다.
Cees Timmerman

11

망막 ,8 5 바이트

,V,,`

온라인으로 사용해보십시오!

Kevin Cruijssen 덕분에 3 바이트를 절약했습니다 !

줄 바꾸기를 구분자로 사용합니다. 우리는 Retina의 역 스테이지와 일부 한계를 사용합니다. 첫 번째 한계는 반전을 적용하기 위해 일치하는 것이므로 모두로 선택합니다 ,. 그런 다음 각 일치 항목의 첫 번째 문자와 마지막 문자를 바꾸고 싶기 때문에 각 문자를 ,,범위에서 시작하여 끝까지의 단계 크기가 0 인 범위로 가져갑니다.


Dangit, 나는 방금 문서를 검색하여 내 대답을 업데이트하기 위해 이와 같은 것을 찾았지만 당신은 나를 이겼습니다. 나는에 대해 알았지 만 V, 그런 지수 1,-2와 함께 사용할 수 있다는 것을 몰랐습니다 . 좋은 것!
Kevin Cruijssen

1
@KevinCruijssen 나는 샌드 박스에있는 동안 약간의 속임수와 한계 범위의 작동 방식을 검토했습니다.
FryAmTheEggman

2
당신은 것 같다 있기 때문에, 제한 범위없이 짧아 질 수 올바른 것을 참으로있어 5 byter의 (워드 프로세서의 단계 제한의 맨 아래에 예로서 주어진) 작품.
Kevin Cruijssen

@KevinCruijssen 니스! 내가 그것을 놓쳤다는 것을 믿을 수 없다.
FryAmTheEggman

3
그래서 5 바이트와 3 개의 다른 문자 만? 미니멀리스트입니다.
Cœur

9

페페 , 107105 바이트

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

@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 바이트를 절약하기 위해 보호의 바인딩으로 이동할 수 있습니다. 온라인으로 시도하십시오!
Laikoni

1
제목에 "Haskell"이라는 이름으로 무엇을했는지 보았습니다. 내 PHP 답변에서 동일한 작업을 수행했습니다.
640KB

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 %였다.
Magic Octopus Urn

1
9 바이트를 찾았지만 레거시 버전에서만 작동합니다.|ʒRćsRćJ,
Kevin Cruijssen

1
너무 나쁘지 않다면 loop_as_long_as_there_are_inputs8 바이트를 알았을 것입니다. [RćsRćJ,이 8 바이트 [는 이론적으로 절대 출력을 사용 하지 않지만 TIO와 같이 메모리가 부족하거나 시간 초과 될 때만 (그리고 후행이 필요합니다) 입력에 개행 문자, 그렇지 않으면 마지막 단어를 계속 사용합니다.)
Kevin Cruijssen

1
불행히도 ð¡단일 단어 입력이 가능 해야 하지만 ð¡εćsÁì}ðý10 바이트에서도 작동합니다.
Emigna

5

J , 23 17 바이트

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

온라인으로 사용해보십시오!


회전하고 적용하여 첫 번째 / 마지막 문자를 바꾸는 아주 좋은 트릭 1 A.!
Galen Ivanov

1
1&A.&.(1&|.)-> ({:,1|.}:)그리고 ::]
ngn

놀라운, 감사합니다
FrownyFrog

정말 놀라운! 다시 한 번 나는 솔루션이 얼마나 간단하고 우아 할 수 있는지에 놀랐지 만, 다른 사람이 해낸 것을 본 후에야 놀랍습니다.
Galen Ivanov

4

루비-p, 42 41 29 바이트

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

온라인으로 사용해보십시오!



@Shaggy 감사합니다. 당신이 내 게시물의 역사를 보면 내가 아마 그 시간 동안 몇 가지 메모를 놓친 그래서, 내가 어떤 대답없이 멀리 8개월위한이었다 보여줍니다, 하하
값 잉크

컨센서스가 8 개월 전에 바뀌 었음을 확신하지만 놓치지 않은 경우를 대비하여 "경쟁이 아닌"또한 더 이상 문제가되지 않습니다.
Shaggy

잘 했어요 규칙에 따라 줄 바꿈을 구분 기호로 사용하고 \ws를 .s로 바꿀 수 있다고 생각합니다 .
histocrat





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]설명으로 만 추가되었습니다.

구분 기호로 탭하십시오. 입력은 후행 줄 바꿈 (또는 탭)을 포함해야합니다. 그렇지 않으면 프로그램은 공백을 입력 할 때 한 번에 한 문자 만 수행 할 수 있으므로 중지시기를 알 수 없습니다.

온라인으로 사용해보십시오 (원시 공백, 탭 및 줄 바꾸기 만).

의사 코드의 설명 :

[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에 아무 것도 주어지지 않으면 문자를 읽으려고 할 때 프로그램이 오류와 함께 종료됩니다 (또는 vii5ard 와 같은 일부 공백 컴파일러에서 입력을 기다리는 동안 중단됨 ).


3

Wolfram Language (Mathematica) , 58 바이트

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

온라인으로 사용해보십시오!

@attinat에서 -22 바이트

@ M.Stern에서 -12 바이트


s StringReplace와 함께 사용 하는 70 바이트StringExpression
attinat

1
StringTake대신에 64 바이트 사용 StringReplace:StringRiffle[StringSplit@##~StringTake~{{-1},{2,-2},{1}},#2,""]&
로마

2
보다 직접적인 접근 방식은 다음과 같습니다.StringReplace[#, a : u ~~ w : u .. ~~ b : u :> b <> w <> a /. {u -> Except@#2}] &
M. Stern

1
{와}는 선택 사항 :)
M. Stern

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시를
Oliver

2

sed, 64 바이트

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

물론 우리는 .대신에 사용할 수 [[:alpha:]]있지만 실제로는 [^ ]43 이어야 하지만 구두점 등은 깨집니다. 를 사용 [a-zA-Z]하면 최대 55 개가됩니다.이 달콤하고 감미로운 사람이 읽을 수있는 엔티티를 따라 가기 시작했습니다.
Rich

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 예, 그러나 67 문자로 가져와야 [^ ]합니다 [^[:space:]].
리치

"구분자"는 분리 문자가 항상 일반 공간임을 보장 할 수 있음을 의미합니다. 어쨌든 문장에서 탭을 사용하는 사람은 누구입니까 ??
가치 잉크

괜찮아. "코드 골프"는 실제로 작업을 수행하는 대신 드론이 구멍에 공을 떨어 뜨릴 수있는 방법을 찾는 게임입니다. 시끄러운 환영에 감사드립니다.
Rich

2

sed , 34 바이트

아마도 패턴 아이디어는 대부분의 RE 도구와 함께 작동합니다 (표준 RE와 확장 RE 사이에 차이가 있음을 알고 있습니다).

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

온라인으로 사용해보십시오!


1
PPCG에 오신 것을 환영합니다! 그분들의 정규식 일치의 욕심이 자연 의미 당신은을 줄일 수 \b경기에서 : 온라인으로보십시오!
Value Ink

@ValueInk에 동의했지만 일치하는 것으로 정확했습니다. 를 제거하면 \b30 바이트가됩니다.
PJF

고급 정규식에는 -E를 사용하고 이스케이프 처리되지 않은 괄호를 사용할 수 있습니다. .교체 된 문자에 사용 하면 다른 두 문자를 잃을 수 있습니다. 이것은 26 바이트로 줄입니다. 가장 작은 판독 가능한 솔루션 중 하나입니다. s,\b(.)(\w*)(.)\b,\3\2\1,g
리치

1
-아니, 내가 틀렸다, 당신 \w은 끝에 s 가 필요하다 . 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 

독립형 PC DOS 실행 파일 명령 행 인수를 통해 입력하고 화면에 출력합니다.

여기에 이미지 설명을 입력하십시오

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%

입력을 명령 행 매개 변수로 사용합니다. 문자열 조작은 배치에서 기껏해야 두려운 일이므로 한 글자로 된 특수 단어를 사용하면 도움이되지 않습니다.


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)

실제로는 공백을 사용할 수 있지만 줄 바꾸기를 구분 기호로 사용합니다.

온라인으로 사용해보십시오!


84 바이트에 대해 SelectMany (즉, 맵핑 및 병합)를 수행하지만 단일 후행 공백을 출력합니다. 온라인으로 사용해보십시오!
내 대명사는 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));}

TIO


한 글자로 된 단어에도 적용됩니까?

@Neil no 내가 나쁘기 때문에. 나중에 수정하겠습니다.
벤자민 Urquhart

109 구분자로 줄 바꿈을 사용하여 109
무지의 구현


1

스칼라, 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),' ')

입력은 varchar 필드 v가있는 기존 테이블 t 를 통해 이루어집니다. , 우리의 IO 표준 당 .

뒤에서 앞으로 읽으면 STRING_SPLIT구분 기호를 통해 문자열을 개별 행으로 나누고 STUFF지정된 위치의 문자를 수정 한 다음 STRING_AGG다시 함께 매시합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.