내 슬래시를 그립니다.


60

프로그래머는 아마도 슬래시와 슬래시에 대해 들었을 것입니다. 그러나 다운 슬래쉬에 대해 들어 보셨습니까? 그때 당신은 많은 슬래시를 취하고 끝을 연결하고 내려갑니다.

오늘날의 과제를 해결하려면 순전히 슬래시로 구성된 문자열을 사용하고 해당 슬래시를 모두 아래로 연결하는 줄에 출력하는 프로그램이나 함수를 작성해야합니다. 예제를 보면 더 명확해질 것입니다. 문자열이 주어지면 \\\//\/\\다음을 출력해야합니다.

\
 \
  \
  /
 /
 \
 /
 \
  \

다음은 몇 가지 설명입니다.

  • 라인 당 하나의 슬래시가 있어야합니다.

  • 첫 번째 줄에는 선행 공백이 없습니다.

  • 슬래시 쌍마다 :

    • 서로 다르면 같은 열에 그려집니다. 예를 들어 다음 \/을 제공합니다.

      \
      /
      
    • 문자가 동일하면 아래쪽 문자가 가리키는 방향 에 있습니다. 즉, 백 슬래시의 경우 오른쪽으로 이동하고 슬래시의 경우 왼쪽으로 이동합니다. 그래서 \\//줄 것이다

      \
       \
       /
      /
      
  • 출력의 시각적 모양을 변경하지 않는 한 각 줄마다 추가 공백이있을 수 있습니다. 최대 1 개의 후행 줄 바꿈도 허용됩니다. 여분의 선행 공백 은 허용되지 않습니다 !

더 간단하게 유지하기 위해 문자열에 슬래시가 너무 많이 포함되지 않는다고 가정 할 수 있습니다. 다시 말해서, 입력의 접두어에는 백 슬래시보다 더 많은 슬래시가 포함 되지 않으므로 입력이 같 \\////거나 //주어지지 않습니다. 이것은 또한 모든 입력이 백 슬래시로 시작한다는 것을 의미합니다.

입력을 문자열 리터럴로 가져 오는 경우 필요한 경우 백 슬래시를 이스케이프 처리 할 수 ​​있습니다. 또한 비어 있거나 슬래시 이외의 문자를 포함하는 입력을 처리 할 필요가 없습니다.

합리적인 형식으로 출력 할 수 있습니다 .

평소와 같이 이것은 문제이므로 다소 어려운 언어를 선택하더라도 가능한 한 가장 짧은 솔루션을 만드십시오. 바이트를 제거하는 데 사용한 흥미로운 기술을 설명하는 보너스 포인트!

#Input
\\\\\\\\\\\

#Output
\
 \
  \
   \
    \
     \
      \
       \
        \
         \
          \

#Input
\\\//\\/\//\\///

#Output
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
백 슬래시는 성가신 양의
탈출구를 만듭니다

답변:


20

GNU 세드, 20

s|\\|&^L|g
s|/|^H/^L^H|g

그 주 ^L^H문자 폼 피드와 백 스페이스 문자 (0x12를하고 0x8이에게)입니다.

이 답변은 백 스페이스 및 용지 공급 문자를 사용하여 커서를 움직여 작동합니다. 슬래시 / 백 슬래시는 공백으로 채워지지 않습니다. 확실하지 않으면이 답변의 자격이 없습니다. 이것은 TIO에서는 작동하지 않지만 xtermand 같은 일반적인 터미널에서는 잘 보입니다 gnome-terminal.

이 sed 스크립트를 다음과 같이 다시 작성하십시오.

base64 -d <<< c3xcXHwmDHxnCnN8L3wILwwIfGc= > downslash.sed

다음과 같이 실행하십시오.

$ echo '\\\//\/\\' | sed -f downslash.sed
\ 
 \ 
  \ 
  /
 /
 \ 
 /
 \ 
  \ 

$ 

설명:

s|\\|&^L|g     # move cursor down after every "\"
s|/|^H/^L^H|g  # move cursor left before every "/", then after, down and left again

14

, 13 12 11 바이트

FS¿⁼ι/↓¶/↘ι

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 추가 기능을 지원합니다 //. 설명:

 S              Input string
F               Loop over each character
  ¿             If
    ι           Current character
   ⁼            Equals
     /          Literal /
      ↓¶        Move left
      ↓ /       Print a / downwards
         ↘ι     Else it's a \ so print that down and right

내 생각 ↓¶= 설명은 옳지 않다에서 "왼쪽으로 이동".
Jonathan Allan

@JonathanAllan 맞습니다 (줄 바꿈 인쇄 = 왼쪽으로 이동). "print \n/down" 이라고 말하는 것이 더 명확 할 것입니다.
ASCII 전용

나는 print \n/ down문자 그대로의 번역보다는 코드의 효과를 설명하는 것이 더 도움이된다고 생각했기 때문에 말하지 않았다 .

1
(뺨의 혀 : 효과 설명 = MyCode - Do the spec). 나는 비록 지금 그것을 얻을 효과가 왼쪽으로 이동하는 것입니다; "왼쪽으로 이동 (인쇄 방향으로 줄 바꾸기를 인쇄하여)"이라고 말하면됩니다.
Jonathan Allan

가장 간결하고 자명 한 모든 것!
j4hangir


10

/// , 119 바이트

///에는 입력 명령이 없으므로 입력을 프로그램에 포함해야합니다. 이를 위해 입력 문자열이 이스케이프 처리없이 간단히 추가됩니다.

/=/\/\///M/
|%%=N/%|||=C/BA=\/\\/\/C\\=C\\/CbC=B\A\=CfC=AB=/A/%Mxy=B/|z%N|x|y% %N%x|y%%% |fzN%M%b|zN|M|%
=|/AB\\=%/|=AC

작동 원리

  • 다음에서는 \\/\//시연을 위해 프로그램에 입력 내용이 추가됩니다.
  • 인라인 코드에서 줄 바꿈을 나타내는 데 사용됩니다.

약어

/=/\/\///M/␤|%%=N/%|||=C/BA=프로그램 의 시작 부분 에는 골프 약어를 대체 할 수 있습니다.

  • =로 확장 //, M␤|%%, N%|||CBA.
  • 이 후 현재 프로그램은

    /\/\\/\/BA\\//BA\\/BAbBA//B\A\//BAfBA//AB///A/%
    |%%xy//B/|z%%||||x|y% %%|||%x|y%%% |fz%|||%
    |%%%b|z%||||
    |%%|%
    //|/AB\\//%/|//ABA\\/\//
    

입력 레코딩

다음 단계에서는 추가 된 입력 문자열을보다 유용한 형식으로 변환합니다. ///의 두 명령 문자로만 구성되므로 기본 프로그램을 조작하지 않도록주의해야합니다.

  • 첫 번째 실질적 /\/\\/\/BA\\/대체는 문자열을 /\로 바꿉니다 /BA\.
    • 현재 기본 프로그램에 포함되어 /\있지 않으므로이 대체 프로그램은 영향을 미치지 않습니다.
    • 그러나,이 시퀀스에 첨부 된 입력 문자열 흩어 \시퀀스 뒤에 S /투게더와 S, ABA기본 프로그램의 끝이 가능한 다음 치환체로 반복 할 수있다.
    • ABA앞에 접두사를 포함하면 예제 입력 문자열이됩니다 ABA\\/BA\//.
  • 다음 대체는 /BA\\/BAbBA/로 대체 BA\됩니다 BAbBA.
    • /// 대체는 더 이상 일치하지 않을 때까지 반복되기 때문에 \입력 문자열의 모든 s를 반복 합니다. 이제 접두사가 붙습니다.ABAbBAbBA/BAbBA//
  • 마찬가지로, /B\A\//BAfBA/변경 BA/BAfBA관통 반복, /S.
    • \그렇지 않으면 이전 대체에 의해 엉망이되기 때문에이 대체에서 탈출 해야합니다.
    • 입력이 이제로 바뀌 었습니다 ABAbBAbBAfBABAbBAfBAfBA.
  • 그런 다음 /AB//인코딩의 불필요한 부분을 제거하여로 바꿉니다 AbBAbBAfBAbBAfBAfBA.
    • 이것은 또한 제거 AB로부터 /|/AB\\/나중에 상술로부터 보호하기 위해 필요했던 프로그램에 교체 /\조작.
    • 이 시점 \에서 원래 입력 문자열의 AbB모든 /것이되고 모든 것이되었습니다 AfB. ( b그리고 f뒤로 앞으로에 대한 서.) 길 잃은있다 A끝이.
  • 다음 두 대체는 모든 As 및 Bs를 최종 단계에서 실행되는 프로그램 조각으로 바꿉니다. 대체 문자열에서 %s 및 |s는 각각 /s 및 \s 가 될 내용을 인코딩합니다 . 여기에는 두 가지 이점이 있습니다.
    • 달리 /\%s와 |의 복사 할 탈출하지 않아도됩니다.
    • 대체 문자열은 하위 문자열을 포함하지 /\않으므로 이전 조작으로 인해 엉망이되었습니다.
  • 그 후, 치환 /|/\\/(이전의 /|/AB\\/)은 이제 |s를 디코딩하고 , 이후에 다음 /%/|//이 s를 /%/\//디코딩하고 디코딩합니다 %.

최종 단계에서의 프로그램 구조

이 시점에서 기본 프로그램은 모든 대체를 실행했으며 남아있는 것은 입력 문자열의 프로그램 인코딩입니다.

  • 각 입력 문자는 서브 프로그램이되었습니다

    /
    \//xy*\z//\\\\x\y/ //\\\/x\y/// \fz/\\\/
    \///b\z/\\\\
    \//\/
    

    (후단 개행) 여기서 *어느 나타내는 f오리지널 용 /또는 b원래 대한 \.

  • /␤\//xy프로그램의 끝에 불완전한 대체 명령도 있습니다 /. 이는 이전 서브 프로그램의 대체에 필요한 것을 제공하는 것 외에는 효과가 없습니다 .

공유 부분 문자열

서브 프로그램을 통한 최종 반복이 시작되기 전에 각 문자의 서브 프로그램 형식 이후에 경계를 교차하는 서브 스트링이 \/␤/있습니다.

  • 이 부분 문자열은 공유 전역 상태로 사용됩니다. 프로그램의 나머지 모든 대체는 동일하고 동시에 그것들을 조작하여 각 입력 문자의 하위 프로그램 끝에서이 공유 하위 문자열의 사본 ( /대체를 고정하는 final 제외 )이 해당 행을 인쇄하도록 실행됩니다 캐릭터.
  • 하위 문자열의 초기 버전은 just을 포함하는 행을 인쇄하는 것을 나타내며 /, 첫 번째 입력 문자가 행의 시작 부분에 인쇄되도록하는 올바른 가상 "이전 행"입니다.
  • 일반적으로 인쇄 단계에서 공유 하위 문자열은 여러 공백 \\또는 \/줄 바꿈과 다음으로 구성 /됩니다.

문자 서브 프로그램 실행

다음 대체 중 일부는 \내부에 여분 의을 포함하여 서로 일치하고 엉망이되는 것을 방지합니다 (다른 서브 프로그램의 다른 사본 포함). 이를 달성하는 것은 모두 이유입니다 x및이 y필요하다.

  • 문자 서브 프로그램의 첫 번째 대체, /␤\//xyf\z/또는 /␤\//xyb\z/의 원인이 ␤/될 수있는 공유 문자열의 끝에서 xyfz또는 xybz바로 아래, \/또는 \\.
  • 대체는 /\\\\x\y/ /대체 \\xy공백 및 대체는 /\\\/x\y//대체 \/xy아무것도에 의해.
    • 인쇄 된 이전 입력 문자가 각각 \또는 /일 때 적용됩니다 .
    • 공유 문자열 이제 인쇄 구역의 해당 수를 포함 \하여, 다음 다음 fz또는 bz.
  • 대체 / \fz/\\\/␤\//​ fz로 대체 되고 \/␤//b\z/\\\\␤\//대체 bz됩니다 \\␤/.
    • 현재 입력 문자가 각각 /또는 \일 때 적용됩니다 .
    • 첫 번째는 /올바르게 놓을 여분의 공간을 먹는다 .
      • 이 공간이 없으면 (즉, 접두사 조건을 위반하는 입력) 다음 대체는 잘못 해석되어 많은 정크를 인쇄하며 대개 ///무한 루프 인을 누르십시오 .
    • 각각 고유 한 문자를 인쇄하기 위해 올바른 명령을 추가하고 ␤/공유 부분 문자열의 끝에서 원본 을 복원합니다 .
  • 문자 서브 프로그램이 공유 서브 스트링의 사본에 도달하여 행을 인쇄 할 준비가되었습니다.

마지막 문자 서브 프로그램이 실행 된 후 프로그램의 나머지 부분은입니다 /␤\//xy. final이 누락 된 불완전한 대체이므로 /프로그램은이를 생략하고 정상적으로 정지합니다.


1
업무에 적합한 언어! Lol
DJMcMayhem

6

젤리 , 14 바이트

=”\ðḤ’+\_⁸⁶ẋżY

결과를 인쇄하는 전체 프로그램.

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

어떻게?

=”\ðḤ’+\_⁸⁶ẋżY - Link: list of characters, s    e.g. "\\\//\\/"
 ”\            - literal '\'                         '\'
=              - equal? (call this e)                [1, 1, 1, 0, 0, 1, 1, 0]
   ð           - new dyadic chain f(e, s)
    Ḥ          - double                              [2, 2, 2, 0, 0, 2, 2, 0]
     ’         - decrement                           [1, 1, 1,-1,-1, 1, 1,-1]
      +\       - cumulative reduce with addition     [1, 2, 3, 2, 1, 2, 3, 2]
         ⁸     - chain's left argument, e            [1, 1, 1, 0, 0, 1, 1, 0]
        _      - subtract (# of leading spaces)      [0, 1, 2, 2, 1, 1, 2, 2]
          ⁶    - literal ' '                         ''
           ẋ   - repeat                              [""," ","  "," "," "," ","  ","  "]
            ż  - zip with s                          [["",'\'],[" ",'\'],["  ",'\'],["  ",'/'],[" ",'/'],[" ",'\'],["  ",'\'],["  ",'/']]
             Y - join with newlines                  ["",'\','\n'," ",'\','\n',"  ",'\','\n',"  ",'/','\n'," ",'/','\n'," ",'\','\n',"  ",'\','\n',"  ",'/']
               - implicit print - this smashes the lists (shown as "..." above) and the characters (shown as '...' above) together.




5

MATL , 23 19 18 바이트

@Sanchises 덕분에 1 바이트 할인

fGqoEq1yd~h*YsGZ?c

입력은 작은 따옴표로 묶인 문자열입니다.

온라인으로 사용해보십시오! 또는 테스트 사례를 확인하십시오 ( 1 , 2 , 3) .

설명

'\\\//\/\\'예를 들어 입력 을 고려하십시오 .

f      % Implicit input. Array of indices of nonzeros. Since all chars in the input
       % have nonzero code point, this gives [1 2 ... n] where n is input length
       % STACK: [1 2 3 4 5 6 7 8 9]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], '\\\//\/\\'
qo     % Subtract 1 from (the code-point) of each char and then compute modulo 2.
       % This transforms '\' into 1 and '/' into 0
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 0 1 0 1 1]
Eq     % Double, subtract 1. This transforms 0 into -1
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1]
1y     % Push 1 and duplicate from below
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 1 -1 -1 1 -1 1 1]
d~     % Consecutive differences, logical negation: gives 1 if consecutive entries
       % are equal, 0 otherwise
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 0 1 0 0 0 1]
h      % Horizontally concatenate
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], [1 1 1 0 1 0 0 0 1]
*      % Element-wise multiplication
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 -1 0 0 0 1]
Ys     % Cumulative sum
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3], '\\\//\/\\'
Z?     % Build sparse matrix with those row indices, column indices, and values
       % STACK: [92  0  0;
                  0 92  0;
                  0  0 92;
                  0  0 47;
                  0 47  0;
                  0 92  0;
                  0 47  0;
                  0 92  0;
                  0  0 92]
c      % Convert to char. Char 0 is shown as space. Implicitly display
       % STACK: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']

색인을 얻기 위해 약간 다른 알고리즘으로 1 바이트를 줄입니다 .
Sanchises

@Sanchises 매우 적절한 편집에 감사드립니다!
Luis Mendo

5

C # (. NET 코어) , 74 88 82 78 77 76 + 18 바이트

Kevin Cruijssen 덕분에 -1 바이트

s=>s.Select((x,i)=>$"{x}".PadLeft((x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)))

각 줄마다 하나씩 문자열 모음을 출력합니다. 바이트 수에는 다음이 포함됩니다.

using System.Linq;

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

77 바이트 응답에 대한 설명 :

s =>                              // Take input, a string
    s.Select((x, i) =>            // Replace every character with:
        $"{x}"                    //     The character as string
        .PadLeft(                 //     Pad with this many spaces:
            s.Take(i)             //         Take characters, in the input string, preceding current one
            .Sum(y =>             //         Sum them by:
                y < 92 ? -1 : 1   //             If it's a \ add 1, if / subtract 1
            )
            + (x - s[0]) / 45 + 1 //         If first slash is a / add one more space, if current slash is a \ add one more space (I got this through power of MATHS!)
                                  //         How I arrived at this function:
                                  //         + x / 48        If current slash is a \ add one more space
                                  //         - s[0] / 48 + 1 If the first slash is a / add one more space
        )
    )

3
작동하지 않습니다 /\\/\\/.

@Neil 그것을 지적 해 주셔서 감사합니다! 결정된.
Grzegorz Puławski

1
나는 그것이 오랜만 것을 알고,하지만 당신은 변경하여 바이트를 저장할 수 s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
케빈 Cruijssen

멋진 사람 @KevinCruijssen!
Grzegorz Puławski

4

05AB1E , 14 바이트

ÇÈx<ηOs-W-ISú»

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

설명

Ç                # convert input string to a list of ascii codes
 È               # check each for evenness
  x              # push a doubled copy
   <             # decrement
    η            # compute prefixes
     O           # sum each prefix
      s          # swap the unaltered copy of evenness to the top
       -         # subtract from the prefix-sum list
        W-       # subtract the minimum value
          IS     # push input split to a list of chars
            ú    # pad each with the number of spaces computed
             »   # join on newline

1
작동하지 않습니다 /\\/\\/.

Ç¥.¥0<.SηOv¹Nèy<ú, 이진에
Magic Octopus Urn

3

R , 122 121 바이트

주세페 덕분에 -1 바이트

x=el(strsplit(scan(,""),""));n=seq(x);y=x>"/";for(i in n)cat(rep(" ",diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]),x[i],"\n",sep="")

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

여분의 공백이있는 경우 :

x = el(strsplit(scan(,""),""))
n = seq(x)
y = x>"/"
for(i in n) {
  cat(rep(" ", diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]), x[i], "\n", sep="")
}

설명 :이 대답은 선행 공간의 수가 각 행을 -1 씩 더한 /이전 및 현재 행 의 수를 관찰 한 결과를 기반으로합니다 .

N 슬래시 y가있는 경우 변수 는 길이 N의 벡터이며 각 위치에 대해 1 \, 그렇지 않으면 0입니다. 따라서 한 줄당 선행 공백 수를 변경하려면를 계산 y[1:(N-1)] + y[2:N] - 1합니다. 이 함수 diffinv는 이러한 차이를 0부터 시작하여 시퀀스로 변환합니다. 나머지는 각 행을 필요한 후행 공백 수로 조립 한 다음 관련 슬래시와 줄 바꿈을 수행하면됩니다.


1
119 바이트에 대해 상당히 다른 접근 방식을 취하여 접근 방식을 결합 할 수 있는지 궁금합니다. ( diffinv;의 좋은 사용 ) 또한 당신은 y=x>")"-1 바이트를 설정할 수 있습니다
Giuseppe

@Giuseppe 별도의 답변으로 게시해야합니다. 당신은 할 필요를 피하는 좋은 방법입니다 strsplit. 이것은 항상 살인자입니다. 당신은 또한 유명한을 활용할 수 있습니다 diffinv!
user2390246

1
또한 library(methods)헤더 를 넣으면 (패키지가 기본 R이므로 패널티가 없어도 괜찮습니다) 사용할 수 있다고 생각합니다 el. 또한, diffinv만큼 긴 것으로 밝혀졌습니다 cumsum! :)
Giuseppe

그렇습니다, 나는 그것을 또한 깨닫고있었습니다. 그것은 그 맥락에서 잘 작동하지 않습니다
user2390246

글쎄, 나는 해결 방법을 생각해 냈지만, 그래, 그 *S일은 문제를 일으킨다.
주세페

3

Brain-Flak , 175 바이트 (174 자 + 1 개 플래그)

-c플래그로 실행하십시오 .

{(({})<(())>){({}[()]<([{}])>)}{}(({}<>{}<><({}<>)((()()()()()){})>)<{({}[()]<((((()()()()){}){}){})>)}>{})<>}<>{}{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

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

설명

{ for each char in the input...
  (({})<(())>){({}[()]<([{}])>)}{} push 1/-1 for backslash/slash
  ((
   {}<>{}<> add the 1/-1 to a running total
   <
    ({}<>) move slash/backslash to other stack
    ((()()()()()){}) newline
   >
  )<{({}[()]<((((()()()()){}){}){})>)}>{}) spaces
  <>
}<>{} end for
reverse data order, removing one space before backslash
{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

나는 항상 뇌파를 찬성했다. : D
DJMcMayhem

3

루비 , 80 76 바이트

manatwork 덕분에 -4 바이트

puts"\\";$*[i=0].chars.each_cons 2{|b,c|puts" "*(b==c ?b==?/?i-=1:i+=1:i)+c}

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

설명:

puts "\\"           # Output the first backslash
$*[i=0].            # Get the first argument and set i to 0
chars.              # Go through every individual character,
each_cons 2 { |b,c| # In pairs to compare easily
                    #
    puts " " *      # Decide how many padding spaces to use based on the value
                    # of i. The expression inside the parenthesis will return
                    # i but before that, it will increment/decrement i based
                    # on what the previous character was.
                        #
    ( b==c ?            # if b == c
        b==?/ ?         #   if b == "/" (Going to the left)
            i-=1        #       return decremented i
            :           #   else        (Going to the right)
            i+=1        #       return incremented i
        :               # else
        i) +            #   return i
                    #
                c   # Finally, write the second of the characters that we're
}                   # iterating through.

1
어떤 루비 버전? 2.3.3 코드 블록이 다음과 같은 경우 매개 변수를 괄호로 묶어야합니다 .each_cons(2){…}. .each_char→ 를 교체하여 저장할 수 있습니다 .chars.
manatwork

@manatwork 내 루비 버전은 2.4.1입니다. 문자에 대한 제안에 감사드립니다, 나는 그것에 대해 몰랐습니다.
Pazzaz

i+=중첩 된 삼항 표현식의 시작 부분 으로 이동 하고로 끝나는 방법으로 2 바이트를 더 절약 할 수 있습니다 -1:1:0.
benj2240

3

자바 (8) 121 118 110 109 102 바이트

a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}

@Nevay 의 비트 별 마술 덕분에 -7 바이트 . :)

설명:

여기에서 시도하십시오.

a->{                    // Method with char-array parameter and String return-type
  String r="";          //  Return-String
  int s=0,              //  Amount of spaces
      p=0,              //  Previous characters (starting at 0)
      i;                //  Index-integer
  for(char c:a){        //  Loop over the input
    for(i=s+=p+(p=c-63)>>5;
                        //   If the current does not equals the previous character
                        //    Leave `s` the same
                        //   Else-if it's a '\':
                        //    Increase `s` by 1
                        //   Else (it's a '/'):
                        //    Decrease `s` by 1
                        //   And set the previous character to the current in the process
        i-->0;r+=" ");  //   Append `r` with `s` amount of spaces               
    r+=c+"\n";          //   Append the character + a new-line to the result
  }                     //  End of loop
  return r;             //  Return result-String
}                       // End of method

1
102 바이트 :a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}
Nevay

@Nevay 감사합니다. 비트 단위 작업으로 단축 할 수는 있지만 알아낼 수는 없다는 것을 알았습니다. 주로 >>/ >>>/ <<... 의 효과를 시도하는 것을 잊었 기 때문에 &/ |/ ~/ ^..>.>로 일부 항목 만 확인했습니다 .
Kevin Cruijssen

3

C (GCC), 137 (134) 97 바이트

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

• ATaco 덕분에 3 바이트

• Digital Trauma & ThePirateBay 덕분에 37 바이트

i,d;f(char*s){char c=s[i],n=s[++i];if(c){printf("%*c%c\n",d+1,c);(c-n)?d:(c==47)?--d:++d;f(s);}}

문자열을 가져 와서 슬래시를 인쇄하는 단순한 재귀 함수만으로는 너무 멋진 것은 아닙니다. 입력은 백 슬래시를 먼저 벗어나야합니다.

용법

f("\\\\\\//\\/\\\\",0,0);

언 골프

이것은 오래된 답변입니다. 업데이트 된 온라인 링크를보십시오!

f(char *s, i, d) {
    char c=s[i], n=s[++i];
    if(!c) return;
    for(int j=0; j<d; j++) printf(" ");
    printf("%c\n",c);
    f(s, i, (c!=n)?d:(c=='/')?d-1:d+1);
}

산출

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


당신은 대체 할 수 c=='\0'!c같은 효과.
ATaco

정말 고마워 솔루션을 업데이트했습니다!
수면

printf("%*s%c", n, "", c)n 개의 공백이있는 문자 c를 인쇄하는 데 사용할 수 있습니까 ?
디지털 외상

나는 당신이 대체하여 몇 바이트를 저장할 수 있습니다 확신 (c!=n)c-n및 삼항 표현을 정리. 와 동일합니다 (c=='/'). 또한 '/'리터럴 숫자로 바꿀 수 47있습니다. 총 7 바이트라고 생각합니다.



3

레티 나 , 47 바이트

^|\\
 $&
+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3
m`^ 

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

^|\\
 $&

각 줄의 시작과 앞에 공백을 추가하십시오 \.

+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3

문자열의 처음 두 문자를 고려하십시오. 첫 번째가 인 경우 /들여 쓰기를 줄여야합니다. 이것은 캡쳐에 앞의 공간을 포함시킴으로써 달성된다 (이것은 항상 첫 번째 스테이지가 추가했기 때문에 존재한다). 두 번째가 a \\이면 증가해야합니다. 이는 첫 번째 단계가 캡처에 추가 한 공간을 포함하여 수행됩니다. 두 번째 문자에 올바른 들여 쓰기가 주어지면 두 번째 및 세 번째 문자 등의 단계가 반복됩니다.

m`^ 

여분의 들여 쓰기를 제거하십시오.

나는 숯불 답변과 같은 슬래시 조합을 허용하는 94 바이트 버전을 작성 했습니다. 온라인으로보십시오! 설명:

.$
¶$.`$* $&

마지막 슬래시를 가져 와서 자체 라인의 동일한 위치에 들여 쓰기하여 볼을 굴립니다.

/
 /

모든 슬래시 앞에 공백을 붙여서 캡처 할 수 있도록하십시오.

+`^(.*)( /|\\)¶( *)( \\|/)
$1¶$3$2¶$3$4

입력의 마지막 슬래시를 반복해서 입력하여 자체 줄에 아래 줄의 슬래시와 맞 춥니 다.

+ms`^(?<!^[\\/].*) (?!.*^[\\/])

남은 들여 쓰기를 삭제하십시오.

G`.

이제 빈 입력을 삭제하십시오.


2

루아 , 96 바이트

c=0 for s in(...):gmatch(".")do c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end

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

루아에서 내가 만들 수있는 가장 짧은 것. 입력은 명령 행에서 가져옵니다.

이것은 몇 가지 트릭을 사용합니다.

  1. (...):gmatch(
    이것은 명령 행에서 단일 문자열을 Lua 프로그램으로 가져 오는 가장 짧은 형식이어야합니다. ...Lua 의 표현식은 함수 선언에 지정되지 않은 varargs에 사용되는 함수에 초과 매개 변수를 캡처합니다. Lua 프로그램의 본체는 명령 줄 인수를 매개 변수로 사용하여 함수로 호출되므로 명령 줄 인수는로 끝납니다 ....
    그 주위의 괄호는 잠재적으로 다중 값 ...식을 단일 값 식으로 바꿉니다. 이 (약간 놀라운) 예를 고려하십시오.
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. Lua 파서는 두 문장의 토큰이 명확하게 분리되고 유효한 Lua 코드 인 텍스트에 대한 해석이 하나만있는 한 줄 종결 자 또는 문장 사이의 공백이 필요하지 않습니다.
  3. 남용 and/ or논리 "x는 다음 다른 값 2를 값 1 경우"를 참조하십시오.
    Lua의 and연산자는 거짓 인 경우 첫 번째 인수를 반환합니다. 그렇지 않으면 두 번째 인수를 반환합니다. or이 truthy 경우 연산자는 첫 번째 인수를 반환 그렇지 않으면 두 번째 주장.
  4. p초기화가 필요하지 않습니다.
    p==s입력에 관계없이 루프의 첫 번째 실행에서 항상 거짓이어야합니다. p루프에 들어가기 전에 값을 설정하지 않으면 (이를 떠나고 nil) 바이트가 절약됩니다.

누구나 루아에서 골프를 칠 수 있습니까?


gmatch를 사용하는 대신 gsub를 사용하여 2 바이트를 절약 할 수있었습니다. c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyKeyboard

글쎄, 그건 중요하지 않습니다. 다음 답변에서와 같이 변경 gmatch(".")하여 2 바이트를 쉽게 절약 할 수 있습니다 gmatch".".
QuertyKeyboard

@QuertyKeyboard 이상합니다 ... 실제로이 코드의 첫 번째 버전에서 gsub를 이와 같이 정확하게 사용했지만 어떻게 든 더 짧아지기 때문에 대신 gmatch로 전환했습니다. 나는 내가 무엇을 다르게했는지 알지 못한다. 불행히도 파일을 덮어 썼다.
Jonathan S.


2

R , 119 바이트

function(s)for(i in 1:nchar(s))cat(rep(" ",cumsum(c(0,!diff(S<-(utf8ToInt(s)>48)*2-1))*S)[i]),substr(s,i,i),"
",sep="")

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

이것은 user2390246의 답변 과 약간 다릅니다 . 그들은 각각 문자열을 반복하여 특정 수의 공백 문자를 인쇄 한 다음 적절한 /\문자를 인쇄합니다.

그러나 문자열을 분할하지 않고 대신 문자를 UTF-8 인코딩 값으로 바꾸는 대신 숫자를 직접 산술 할 수있어 몇 바이트 만 절약되었습니다.


방금 이것에 대해 더 깊이 생각해
보니

@ user2390246 나는 그것을 고쳤다! 괄호를 잘못 배치했지만 지금 diffinv은 제대로 작동하지 않습니다.
주세페


2

C # (. NET 코어) , 60/65 바이트

더 짧은 C # 버전을 시도했습니다.

s=>{int i=0;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

"이것은 또한 모든 입력이 백 슬래시로 시작한다는 것을 의미합니다." 또는 "/"시작을 해결하는 상당히 길다

s=>{int i=s[0]&1;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

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


사이트에 오신 것을 환영합니다! :)
DJMcMayhem

2

루아 , 88 84 바이트

개선 된 버전 (QuertyKeyboard 덕분에 4 바이트)

s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)

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

원본 버전 (88 바이트)

루아의 또 다른 시도는 이번에는 카운터 변수 대신 문자열 조작을 사용하는 완전히 다른 접근법입니다.

s=""for c in(...):gmatch"."do s=s:gsub("\\"," "):gsub("/?$",c):gsub(" /","/")print(s)end

언 골프 드 :

s = ""
for c in string.gmatch((...), ".") do --for each character in the input
  --s contains the output from the previous iteration
  s = s:gsub("\\", " ") --Replace backslash with space -> indent by 1
  s = s:gsub("/?$", c) --Remove any / at the end of the string and append c to the string
  s = s:gsub(" /", "/") --Remove a single space in front of any / -> un-indent by 1
  print(s)
end

코드에는 흥미로운 점이 있습니다. (...):gmatch"."
이것은 Lua 파서에서 몇 가지 단점을 사용합니다. Lua가 형식의 코드를 만나면 func "string"이것을로 변환합니다 func("string"). 이것은 print "string"상수 문자열을 인쇄하기 위해 쓸 수 있고 함수 뒤에 단일 문자열 리터럴에서만 작동합니다. 다른 것이 있으면 구문 오류가 발생합니다. 그러나이 구문 설탕은 표현식 중간에 함수 호출과 함께 작동하며 더 놀라운 것은 :메서드 호출 구문 설탕 과 함께 잘 작동합니다 . 결국 Lua는 다음과 같이 코드를 해석합니다.

(...):gmatch"."
-> (...):gmatch(".")
-> string.gmatch((...), ".")

누구든지 세 개의 gsub 호출 중 하나를 제거하는 방법을 생각할 수 있으면 알려주십시오.


1
나는 당신의 다른 답변에서 언급 한 내 gsub 트릭이 이것에 대해 효과가 없다는 것을 알게되어 실망했습니다. 실제로 1 바이트를 추가했습니다. 그러나 나는 그것을 쉽게 포기하지 않을 것입니다. 먼저 코드를 줄이기 위해 gsub를 변수로 저장하려고했습니다. 놀랍게도 내 코드는 정확히 같은 양의 바이트-88입니다. 그러나 gsub를 저장하면 gsub 트릭이 작동 할 수 있음을 깨달았습니다! 다음은 4 바이트를 s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
줄인

@QuertyKeyboard 예, 루프 전에 변수에 gsub를 저장 한 다음 gsub를 세 번 쓰는 대신 그것을 사용하려고 시도했지만 전혀 차이가 없다는 사실에 놀랐습니다. "루프 대신 gsub"와 "store gsub"트릭을 결합하는 것은 정말 깔끔합니다. 감사! :)
Jonathan S.


1

펄, 40 + 2 바이트

/\//&&$.--,say($"x$.,$_),/\\/&&$.++for@F

-F깃발 이 필요합니다 .


1

펄, 34 38 + 1 바이트

두 경우를 처리

s,(/)|.,$"x($1?$c&&--$c:$c++).$&.$/,ge

-p옵션 으로 실행

s,(/)|.,$"x($1?--$c:$c++).$&.$/,ge

편집 : 첫 번째 문자가있을 때 다음 주석이 작동하지 않습니다 /

s,(/)|.,$"x($1?$c--:++$c).$&.$/,ge

그러나 첫 번째 문자가 있으면 출력이 오른쪽에서 한 문자 씩 이동합니다. \


1
작동하지 않습니다 /\\/\\/.

업데이트 된 질문으로 귀하의 원래 34솔루션은 이제 완벽하게 유효합니다
Ton Hospel

1

VBA (Excel), 181 바이트

Sub q()
a = Cells(1, 1)
For x = 1 To Len(a)
c = Mid(a, x, 1)
If c = "\" Then: Debug.Print b & c: b = b + " "
If c = "/" Then: b = Left(b, Len(b) - 1): Debug.Print b & c
Next
End Sub

1
당신은 골프 할 수있는이 아래로 크게 엑셀 VBA과의 사용에 의해 자동 서식 자연을 활용하여 알고리즘을 변경하지 않고 [...]표기 : 나는 128 바이트로 내려 가지고 Sub q For x=1To[Len(A1)] c=Mid([A1],x,1) If c="\"Then Debug.?b;c:b=b+" " If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c Next End Sub
테일러 스콧

내 스크립트를 골프 주셔서 감사합니다. 나는 이것으로부터 무언가를 배웠고 앞으로 적용될 것입니다. :) 그것을 사용하여 데이터를 셀로 직접 가져올 수 있다는 것을 몰랐습니다. 다시 한번 감사드립니다 :)
remoel



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